Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Commit

Permalink
Version 1.1.0 alexa-smart-screen-web-components
Browse files Browse the repository at this point in the history
For more details on this release refer to CHANGELOG.md.

To learn about Alexa Smart Screen Web Components see: https://developer.amazon.com/docs/alexa/web-components/wc-about-web-components.html
  • Loading branch information
Tristan Reeves committed May 19, 2023
1 parent 95bf9aa commit b774b5e
Show file tree
Hide file tree
Showing 27 changed files with 261 additions and 260 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog for alexa-smart-screen-web-components

## [1.1.0]

#### Enhancements
* Support for APL v2023.1.0
* Upgraded the webpack dependency to v5.76.0

## [1.0.0]

Initial public release.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
<p align="center">
<i>Alexa Smart Screen Web Components is a node.js library for smart screen device makers building web applications that interact with the <a href="https://github.com/alexa/avs-device-sdk">AVS Device SDK</a>.</i>
<p align="center">
<a href="https://github.com/alexa/alexa-smart-screen-web-components/tree/v1.0.0" alt="version">
<img src="https://img.shields.io/badge/stable%20version-1.0.0-brightgreen" /></a>
<a href="https://github.com/alexa/alexa-smart-screen-web-components/tree/v1.1.0" alt="version">
<img src="https://img.shields.io/badge/stable%20version-1.1.0-brightgreen" /></a>
<a href="https://github.com/alexa/avs-device-sdk/tree/v3.0.0" alt="DeviceSDK">
<img src="https://img.shields.io/badge/avs%20device%20sdk-3.0.0-blueviolet" /></a>
<a href="https://github.com/alexa/apl-client-library/tree/v2022.1.1" alt="APLClientLibrary">
<img src="https://img.shields.io/badge/apl%20client%20library-2022.1.1-blue" /></a>
<a href="https://github.com/alexa/apl-client-library/tree/v2023.1.0" alt="APLClientLibrary">
<img src="https://img.shields.io/badge/apl%20client%20library-2023.1.0-blue" /></a>
<a href="https://github.com/alexa/alexa-smart-screen-web-components/issues" alt="issues">
<img src="https://img.shields.io/github/issues/alexa/alexa-smart-screen-web-components" /></a>
</p>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "alexa-smart-screen-web-components",
"version": "1.0.0",
"version": "1.1.0",
"private": true,
"description": "Alexa Smart Screen Web Components",
"license": "SEE LICENSE IN LICENSE.txt",
Expand Down
4 changes: 2 additions & 2 deletions packages/alexa-smart-screen-apl/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Alexa Smart Screen APL Module
<p>
<a href="https://github.com/alexa/apl-client-library/tree/v2022.1.1" alt="APLClientLibrary">
<img src="https://img.shields.io/badge/apl%20client%20library-2022.1.1-blue" /></a>
<a href="https://github.com/alexa/apl-client-library/tree/v2023.1.0" alt="APLClientLibrary">
<img src="https://img.shields.io/badge/apl%20client%20library-2023.1.0-blue" /></a>
</p>

The Alexa Smart Screen APL module provides Inter-Process Communication (IPC) components, media elements, and wrappers for integrating the [APL Client Library][apl-client-library] Renderer into your project for presentation of [APL-based][apl-dev-site] Alexa visual content.
Expand Down
4 changes: 2 additions & 2 deletions packages/alexa-smart-screen-apl/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@alexa-smart-screen/apl",
"version": "1.0.0",
"version": "1.1.0",
"description": "APL Client Renderer Wrapper for Alexa Smart Screen Web Components.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand All @@ -23,7 +23,7 @@
"node": ">=14.17.4"
},
"devDependencies": {
"@alexa-smart-screen/common": "^1.0.0",
"@alexa-smart-screen/common": "^1.1.0",
"@alexa-smart-screen/window-manager": "^1.0.0",
"standardized-audio-context-mock": "^8.4.16"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,28 @@
* permissions and limitations under the License.
*/

import { AVSVisualInterfaces, ContentType, DefaultActivityTracker, DefaultFocusManager } from '@alexa-smart-screen/common';
import { APLClient } from 'apl-client';
import { APLVideo } from '../media/APLVideo';
import { IAPLWindowElementProps } from '../window/APLWindowElementProps';
import { APLEvent } from './APLEvent';
import { IAPLRendererInstance, IAPLRenderCompletedPayload } from './APLMessageInterfaces';
import { IPC_CONFIG_APL } from './IPCNamespaceConfigAPL';

export class APLWindowWebsocketClient extends APLClient {
private aplEvent : APLEvent;
private windowId : string;

constructor(aplEvent : APLEvent, windowId : string) {
super();
this.windowId = windowId;
this.aplEvent = aplEvent;
constructor(props : IAPLWindowElementProps) {
// Factory func for creating the APLVideo component that extends the APL MediaPlayerHandle
const mediaPlayerFactory = (mediaPlayer : APL.MediaPlayer) => new APLVideo(
mediaPlayer, AVSVisualInterfaces.ALEXA_PRESENTATION_APL, ContentType.MIXABLE,
props.loggerFactory.getLogger(IPC_CONFIG_APL.namespace),
props.focusManager || new DefaultFocusManager(),
props.guiActivityTracker || new DefaultActivityTracker());
super(mediaPlayerFactory);
this.windowId = props.windowId;
this.aplEvent = props.aplEvent;
}

/**
Expand Down
75 changes: 18 additions & 57 deletions packages/alexa-smart-screen-apl/src/media/APLVideo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,9 @@ import {
PlaybackFocusResolverManager
} from '@alexa-smart-screen/common';
import {
APLRenderer,
AudioTrack,
Component,
FactoryFunction,
IVideoFactory,
PlaybackState,
Video
MediaPlayerHandle,
PlaybackState
} from 'apl-client';

/// Default volume value for the player.
Expand All @@ -40,75 +36,39 @@ export const DEFAULT_VOLUME = 1;
/// Low volume value for the player.
export const LOW_VOLUME = 0.2;

/**
* Factory class which creates APLVideo objects
*/
export class APLVideoFactory implements IVideoFactory {
private focusManager : IFocusManager;
private guiActivityTracker : IGUIActivityTracker;
private logger : ILogger;

private readonly avsInterface : AVSInterface;
private readonly contentType : ContentType;

constructor(avsInterface : AVSInterface,
contentType : ContentType,
focusManager : IFocusManager,
guiActivityTracker : IGUIActivityTracker,
logger : ILogger) {
this.focusManager = focusManager;
this.guiActivityTracker = guiActivityTracker;
this.logger = logger;
this.avsInterface = avsInterface;
this.contentType = contentType;
}

public create(renderer : APLRenderer,
component : APL.Component,
factory : FactoryFunction,
parent ?: Component) : APLVideo {
return new APLVideo(this.avsInterface,
this.contentType,
this.logger,
this.focusManager,
this.guiActivityTracker,
renderer,
component,
factory,
parent);
}
}

/**
* A Video component which adds AVS focus support
*/
export class APLVideo extends Video {
export class APLVideo extends MediaPlayerHandle {
protected static readonly CLASS_NAME = 'APLVideo';
protected static videoIdIterator : number = 0;
private id : number;
private focusManager : IFocusManager;
private focusToken : number;
private playbackFocusResolverManager : PlaybackFocusResolverManager;
private guiActivityTracker : IGUIActivityTracker;
private activityToken : number;
private loggerAPLVideo : ILogger;
private waitForFinish : boolean;
private readonly avsInterface : AVSInterface;
private readonly contentType : ContentType;

constructor(avsInterface : AVSInterface,
constructor(mediaPlayer : APL.MediaPlayer,
avsInterface : AVSInterface,
contentType : ContentType,
logger : ILogger,
focusManager : IFocusManager,
guiActivityTracker : IGUIActivityTracker,
renderer : APLRenderer,
component : APL.Component,
factory : FactoryFunction,
parent ?: Component) {
super(renderer, component, factory, parent);
guiActivityTracker : IGUIActivityTracker) {
super(mediaPlayer);
this.playbackFocusResolverManager = new PlaybackFocusResolverManager(logger);
this.loggerAPLVideo = logger;
this.focusManager = focusManager;
this.guiActivityTracker = guiActivityTracker;
this.avsInterface = avsInterface;
this.contentType = contentType;
this.waitForFinish = false;
this.id = APLVideo.videoIdIterator;
APLVideo.videoIdIterator++;
}

protected static getLoggerParamsBuilder() : LoggerParamsBuilder {
Expand All @@ -135,7 +95,7 @@ export class APLVideo extends Video {
break;

case PlaybackState.PLAYING:
this.activityToken = this.guiActivityTracker.recordActive(`APLVideo-${this.id}`);
this.activityToken = this.guiActivityTracker.recordActive(`${APLVideo.CLASS_NAME}-${this.id}`);
break;
case PlaybackState.BUFFERING: // FALLTHROUGH
case PlaybackState.LOADED: // FALLTHROUGH
Expand All @@ -147,8 +107,9 @@ export class APLVideo extends Video {
/**
* Method to start video playback
*/
public async play(waitForFinish = false) : Promise<void> {
public async play(waitForFinish = false) : Promise<void> {
const functionName = 'play';
this.waitForFinish = waitForFinish;
try {
if (this.audioTrack === AudioTrack.kAudioTrackNone) {
// Focus is not required if there is no audio track
Expand Down Expand Up @@ -213,7 +174,7 @@ export class APLVideo extends Video {
this.player.setVolume(DEFAULT_VOLUME);
if (!this.playbackFocusResolverManager.getPlaybackFocusResolver()) {
// If focus was changed without a playback focus request, ensure we resume playback
await super.play();
await super.play(this.waitForFinish);
} else {
this.playbackFocusResolverManager.onResponse();
}
Expand All @@ -223,7 +184,7 @@ export class APLVideo extends Video {
this.player.setVolume(LOW_VOLUME);
if (!this.playbackFocusResolverManager.getPlaybackFocusResolver()) {
// If focus was changed without a playback focus request, ensure we resume playback
await super.play();
await super.play(this.waitForFinish);
} else {
this.playbackFocusResolverManager.onResponse();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import {
DisplayCssProperty,
OverflowCssProperty} from '@alexa-smart-screen/common';
import { IAPLRendererProps, IAPLRendererWrapperProps } from './APLRendererWrapperConfig';
import { APLVideoFactory } from '../media/APLVideo';
import { APLAudioPlayer, IAPLAudioPlayerProps } from '../media/APLAudioPlayer';
import { IPC_CONFIG_APL } from '../ipcComponents/IPCNamespaceConfigAPL';

Expand Down Expand Up @@ -157,7 +156,6 @@ export class APLRendererWrapper {
environment : this.aplEnvironment,
audioPlayerFactory : this.createAudioPlayer.bind(this),
client : this.client,
videoFactory : new APLVideoFactory(AVSVisualInterfaces.ALEXA_PRESENTATION_APL, ContentType.MIXABLE, this.focusManager, this.activityTracker, this.logger),
supportedExtensions : this.rendererProps.supportedExtensions,
onResizingIgnored : this.wrapperProps.onResizingIgnoredCallback
} as any;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class APLWindowElement extends DisplayWindowElement {
super(props.windowId);
this.props = props;
this.attachShadow({ mode : 'open' });
this.client = new APLWindowWebsocketClient(props.aplEvent, props.windowId);
this.client = new APLWindowWebsocketClient(props);

// Init native renderer component
this.client.initializeRenderer({
Expand Down
41 changes: 16 additions & 25 deletions packages/alexa-smart-screen-apl/test/media/APLVideo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import {
RequestResponsePromiseWrapperWithoutTimeout,
Timer
} from "@alexa-smart-screen/common";
import { AudioTrack, Video, PlaybackState } from "apl-client";
import { APLVideo, APLVideoFactory, DEFAULT_VOLUME, LOW_VOLUME } from "../../src/media/APLVideo";
import { AudioTrack, MediaPlayerHandle, PlaybackState } from "apl-client";
import { APLVideo, DEFAULT_VOLUME, LOW_VOLUME } from "../../src/media/APLVideo";

global.AudioContext = AudioContextMocker.AudioContext as any;

Expand All @@ -39,7 +39,6 @@ describe("@alexa-smart-screen/apl - APL Video functionality", () => {
let focusManager : IFocusManager;
let guiActivityTracker : IGUIActivityTracker;
let aplVideo : APLVideo;
let aplVideoFactory : APLVideoFactory;
let volume : number;

const sandbox : sinon.SinonSandbox = sinon.createSandbox();
Expand All @@ -53,14 +52,11 @@ describe("@alexa-smart-screen/apl - APL Video functionality", () => {
let focusManagerAcquireFocusStub : sinon.SinonStub;
let guiActivityTrackerRecordActiveStub : sinon.SinonStub;
let guiActivityTrackerRecordInactiveStub : sinon.SinonStub;
let aplVideoConstructorStub : sinon.SinonStub;
let mediaPlayerHandleConstructorStub : sinon.SinonStub;
let videoPlayStub : sinon.SinonStub;
let videoPauseStub : sinon.SinonStub;
let videoOnEventStub : sinon.SinonStub;

const MEDIA1_ID = 1;
const MEDIA2_ID = 2;

beforeEach(() => {
loggerFactory = createMock<ILoggerFactory>();
focusManager = createMock<IFocusManager>();
Expand All @@ -69,14 +65,6 @@ describe("@alexa-smart-screen/apl - APL Video functionality", () => {
focusManager.acquireFocus = sandbox.stub();
focusManagerAcquireFocusStub = focusManager.acquireFocus as sinon.SinonStub;

aplVideoFactory = new APLVideoFactory(
AVSVisualInterfaces.ALEXA_PRESENTATION_APL,
ContentType.MIXABLE,
focusManager,
guiActivityTracker,
loggerFactory.getLogger(APLVideoFactory.name)
);

requestResponsePromiseWrapperWithoutTimeoutOnRejectSpy = sandbox.spy(
RequestResponsePromiseWrapperWithoutTimeout.prototype,
"onReject"
Expand All @@ -96,18 +84,24 @@ describe("@alexa-smart-screen/apl - APL Video functionality", () => {
guiActivityTracker.recordInactive = sandbox.stub();
guiActivityTrackerRecordInactiveStub = guiActivityTracker.recordInactive as sinon.SinonStub;

videoPlayStub = sandbox.stub(Video.prototype, "play");
videoPauseStub = sandbox.stub(Video.prototype, "pause");
videoOnEventStub = sandbox.stub(Video.prototype, "onEvent");
videoPlayStub = sandbox.stub(MediaPlayerHandle.prototype, "play");
videoPauseStub = sandbox.stub(MediaPlayerHandle.prototype, "pause");
videoOnEventStub = sandbox.stub(MediaPlayerHandle.prototype, "onEvent");

sandbox.stub(HTMLMediaElement.prototype, 'volume').set((v : any) => {
volume = v;
})

aplVideoConstructorStub = sandbox.stub();
// stub video class super call in the constructor: https://stackoverflow.com/questions/40271140/es2016-class-sinon-stub-constructor
Object.setPrototypeOf(Video, aplVideoConstructorStub);
aplVideo = aplVideoFactory.create(null as any, null as any, null as any);
mediaPlayerHandleConstructorStub = sandbox.stub();
// stub media player handle class super call in the constructor: https://stackoverflow.com/questions/40271140/es2016-class-sinon-stub-constructor
Object.setPrototypeOf(MediaPlayerHandle, mediaPlayerHandleConstructorStub);
aplVideo = new APLVideo(
null as any,
AVSVisualInterfaces.ALEXA_PRESENTATION_APL,
ContentType.MIXABLE,
loggerFactory.getLogger(APLVideo.name),
focusManager,
guiActivityTracker)
});

afterEach(() => {
Expand Down Expand Up @@ -349,7 +343,6 @@ describe("@alexa-smart-screen/apl - APL Video functionality", () => {
return focusToken0;
});

aplVideo["setTrack"](MEDIA1_ID);
aplVideo["setAudioTrack"](AudioTrack.kAudioTrackForeground);
aplVideo.play();

Expand All @@ -362,7 +355,6 @@ describe("@alexa-smart-screen/apl - APL Video functionality", () => {
});

// Call play when focus request for first media is not resolved
aplVideo["setTrack"](MEDIA2_ID);
aplVideo["setAudioTrack"](AudioTrack.kAudioTrackForeground);
await aplVideo.play();

Expand All @@ -377,7 +369,6 @@ describe("@alexa-smart-screen/apl - APL Video functionality", () => {
return focusToken0;
});

aplVideo["setTrack"](MEDIA1_ID);
aplVideo["setAudioTrack"](AudioTrack.kAudioTrackForeground);
await aplVideo.play();

Expand Down
2 changes: 1 addition & 1 deletion packages/alexa-smart-screen-app-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
"node": ">=14.16.1"
},
"devDependencies": {
"@alexa-smart-screen/common": "^1.0.0"
"@alexa-smart-screen/common": "^1.1.0"
}
}
2 changes: 1 addition & 1 deletion packages/alexa-smart-screen-binder-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
"node": ">=14.17.4"
},
"devDependencies": {
"@alexa-smart-screen/common": "^1.0.0"
"@alexa-smart-screen/common": "^1.1.0"
}
}
2 changes: 1 addition & 1 deletion packages/alexa-smart-screen-common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@alexa-smart-screen/common",
"version": "1.0.0",
"version": "1.1.0",
"description": "Common Library for Alexa Smart Screen Web Components.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down
Loading

0 comments on commit b774b5e

Please sign in to comment.