@24i/bigscreen-sdk 1.0.5-alpha.2129 → 1.0.5-alpha.2131

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@24i/bigscreen-sdk",
3
- "version": "1.0.5-alpha.2129",
3
+ "version": "1.0.5-alpha.2131",
4
4
  "description": "SmartApps BIGscreen SDK monorepo",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -103,6 +103,7 @@
103
103
  "./device/resolver/keymap": "./packages/device/resolver/keymap.ts",
104
104
  "./device": "./packages/device/src/index.ts",
105
105
  "./digital-clock": "./packages/digital-clock/src/index.ts",
106
+ "./driver-androidtv": "./packages/driver-androidtv/src/index.ts",
106
107
  "./driver-base/keymap": "./packages/driver-base/src/KeyMap/index.ts",
107
108
  "./driver-base": "./packages/driver-base/src/index.ts",
108
109
  "./driver-browser": "./packages/driver-browser/src/index.ts",
@@ -0,0 +1 @@
1
+ export { DeviceAndroidTV as Device } from '@24i/bigscreen-sdk/driver-androidtv';
@@ -1,4 +1,5 @@
1
1
  import { KeycodeKeyMap, DeviceEventMap } from '@24i/bigscreen-sdk/driver-base';
2
+ import { DeviceAndroidTV } from '@24i/bigscreen-sdk/driver-androidtv';
2
3
  import { DeviceBrowser } from '@24i/bigscreen-sdk/driver-browser';
3
4
  import { DeviceEntone } from '@24i/bigscreen-sdk/driver-entone';
4
5
  import { DeviceHbbTV } from '@24i/bigscreen-sdk/driver-hbbtv';
@@ -39,6 +40,11 @@ const getDevice = () => {
39
40
  info('KreaTV');
40
41
  return new DeviceKreaTV();
41
42
  }
43
+ // any because JavaScriptBridge property is defined on Android TV Bridge platform
44
+ if (typeof (window as any).JavaScriptBridge !== 'undefined') {
45
+ info('AndroidTV');
46
+ return new DeviceAndroidTV();
47
+ }
42
48
  // any because ENTONE property is defined on Entone platform
43
49
  if (typeof (window as any).ENTONE !== 'undefined') {
44
50
  info('Entone');
@@ -0,0 +1,179 @@
1
+ import {
2
+ DeviceBase,
3
+ ConnectionType,
4
+ ScreenSaverStatus,
5
+ VolumeRange,
6
+ } from '@24i/bigscreen-sdk/driver-base';
7
+ import { IJavaScriptBridge } from './types';
8
+ import { getFirmware } from './formatUserAgent';
9
+ import { getKeyMap } from './keymap';
10
+
11
+ interface CustomKeyboardEvent extends KeyboardEvent {
12
+ /** Flag indicating that the driver has already re-emitted this event. */
13
+ bigscreenSdkRelaunched?: boolean;
14
+ }
15
+
16
+ declare global {
17
+ interface Window extends IJavaScriptBridge {}
18
+ }
19
+
20
+ /**
21
+ * Android TV driver implementing API of Android TV Bridge.
22
+ *
23
+ * See https://github.com/24i/prd-smart-ott-androidtv
24
+ */
25
+ export class DeviceAndroidTV extends DeviceBase {
26
+ keyMap = getKeyMap();
27
+
28
+ platformInfo = window.JavaScriptBridge.bridgeJavaScriptToAndroid_GetDeviceInfo();
29
+
30
+ firmware = getFirmware(navigator.userAgent);
31
+
32
+ async initDevice(): Promise<void> {
33
+ this.initKeydownListener();
34
+ this.initKeyupListener();
35
+ this.initNetworkChangeListener();
36
+ }
37
+
38
+ initKeydownListener() {
39
+ window.addEventListener('keydown', this.relaunchKeyEvent, true);
40
+ }
41
+
42
+ initKeyupListener() {
43
+ window.addEventListener('keyup', this.relaunchKeyEvent, true);
44
+ }
45
+
46
+ /**
47
+ * Handles keydown/up events for the BACK key which are dispatched on the document
48
+ * from the Android TV Bridge. We must catch them and re-emit them properly
49
+ * on the active (focused) element in the DOM tree.
50
+ * @param event keyboard event
51
+ */
52
+ relaunchKeyEvent = (event: CustomKeyboardEvent) => {
53
+ if (event.bigscreenSdkRelaunched) { // prevent to relaunch event in loop
54
+ return;
55
+ }
56
+ const { keyCode } = event;
57
+ if (keyCode === this.keyMap.BACK) {
58
+ event.preventDefault();
59
+ event.stopImmediatePropagation();
60
+ const newEvent = new KeyboardEvent(event.type, {
61
+ keyCode, bubbles: true, cancelable: true, composed: true,
62
+ }) as CustomKeyboardEvent;
63
+ newEvent.bigscreenSdkRelaunched = true;
64
+ document.activeElement?.dispatchEvent(newEvent);
65
+ }
66
+ };
67
+
68
+ initNetworkChangeListener() {
69
+ window.addEventListener('online', () => {
70
+ this.triggerEvent('networkchange', { isConnected: true });
71
+ });
72
+ window.addEventListener('offline', () => {
73
+ this.triggerEvent('networkchange', { isConnected: false });
74
+ });
75
+ }
76
+
77
+ reboot(): void {
78
+ let rootPath = '';
79
+ const splitUrl = window.location.href.split('#');
80
+ if (splitUrl.length > 1) rootPath = splitUrl[0];
81
+ window.location.href = rootPath;
82
+ }
83
+
84
+ exit(): void {
85
+ window.JavaScriptBridge.bridgeJavaScriptToAndroid_Back();
86
+ }
87
+
88
+ async getManufacturerName(): Promise<string> {
89
+ return this.platformInfo.deviceBrand || '';
90
+ }
91
+
92
+ async getPlatformName(): Promise<string> {
93
+ return 'AndroidTV';
94
+ }
95
+
96
+ async getPlatformVersion(): Promise<string> {
97
+ return this.platformInfo.osVersion || '';
98
+ }
99
+
100
+ async getDeviceName(): Promise<string> {
101
+ const modelName = await this.getModelName();
102
+ const manufacturerName = await this.getManufacturerName();
103
+ return `AndroidTV ${manufacturerName} ${modelName}`.trim();
104
+ }
105
+
106
+ async getModelName(): Promise<string> {
107
+ return this.platformInfo.deviceModel || '';
108
+ }
109
+
110
+ async getFirmware(): Promise<string> {
111
+ return this.firmware || '';
112
+ }
113
+
114
+ async is4KSupported(): Promise<boolean> {
115
+ return false;
116
+ }
117
+
118
+ async is8KSupported(): Promise<boolean> {
119
+ return false;
120
+ }
121
+
122
+ async getUuid(): Promise<string> {
123
+ return this.getBaseUuid();
124
+ }
125
+
126
+ async getVolume(): Promise<number> {
127
+ return VolumeRange.UNSUPPORTED;
128
+ }
129
+
130
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
131
+ async setVolume(volumePercentage: number): Promise<void> {
132
+ // not supported on AndroidTV platform
133
+ }
134
+
135
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
136
+ async mute(mute: boolean): Promise<void> {
137
+ // not supported on AndroidTV platform
138
+ }
139
+
140
+ async isMute(): Promise<boolean> {
141
+ // not supported on AndroidTV platform
142
+ return false;
143
+ }
144
+
145
+ async getScreenSaver(): Promise<ScreenSaverStatus> {
146
+ // not supported on AndroidTV platform
147
+ return { enabled: false };
148
+ }
149
+
150
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
151
+ async setScreenSaver(status: ScreenSaverStatus): Promise<void> {
152
+ // not supported on AndroidTV platform
153
+ }
154
+
155
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
156
+ async setUserAgent(userAgent: string): Promise<boolean> {
157
+ // not supported on AndroidTV platform
158
+ return false;
159
+ }
160
+
161
+ async isNetworkConnected(): Promise<boolean> {
162
+ return window.navigator.onLine;
163
+ }
164
+
165
+ async getConnectionType(): Promise<ConnectionType> {
166
+ // not supported on AndroidTV platform
167
+ return 'unknown';
168
+ }
169
+
170
+ async getLocalIP(): Promise<string> {
171
+ // not supported on AndroidTV platform
172
+ return '';
173
+ }
174
+
175
+ async getMacAddress(): Promise<string> {
176
+ // not supported on AndroidTV platform
177
+ return '';
178
+ }
179
+ }
@@ -0,0 +1,12 @@
1
+ import { IJavaScriptBridge } from '../types';
2
+
3
+ export const mockJavaScriptBridge: IJavaScriptBridge = {
4
+ JavaScriptBridge: {
5
+ bridgeJavaScriptToAndroid_GetDeviceInfo: () => ({
6
+ deviceBrand: 'Sony',
7
+ deviceModel: 'BRAVIA 4K 2015',
8
+ osVersion: '8.0.0',
9
+ }),
10
+ bridgeJavaScriptToAndroid_Back: () => {},
11
+ },
12
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Parses software version of Android TV from user agent string.
3
+ * @param userAgent User agent string
4
+ * @returns software version string or undefined if not found. Ex. "QTS1.220504.008"
5
+ */
6
+ export const getFirmware = (userAgent: string) => {
7
+ const [
8
+ , firmware,
9
+ ] = userAgent.match(/Build\/([^;]*)/) || [] as Array<undefined>;
10
+ return firmware;
11
+ };
@@ -0,0 +1 @@
1
+ export { DeviceAndroidTV } from './DeviceAndroidTV';
@@ -0,0 +1,9 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ import { KeyMap } from '@24i/bigscreen-sdk/driver-base';
3
+
4
+ export const getKeyMap = () => {
5
+ KeyMap.overrideValues({
6
+ BACK: { keyCode: 4 },
7
+ });
8
+ return KeyMap.generateKeyCodeKeyMap();
9
+ };
@@ -0,0 +1,27 @@
1
+ interface JavaScriptBridge {
2
+ /**
3
+ * It returns device info.
4
+ */
5
+ bridgeJavaScriptToAndroid_GetDeviceInfo: () => {
6
+ /**
7
+ * Device brand. Ex. "Sony"
8
+ */
9
+ deviceBrand: string,
10
+ /**
11
+ * Device model. Ex. "BRAVIA 4K 2015"
12
+ */
13
+ deviceModel: string,
14
+ /**
15
+ * Android version. Ex. "7.0"
16
+ */
17
+ osVersion: string,
18
+ },
19
+ /**
20
+ * It simulates a native Android back press.
21
+ */
22
+ bridgeJavaScriptToAndroid_Back: () => void,
23
+ }
24
+
25
+ export interface IJavaScriptBridge {
26
+ JavaScriptBridge: JavaScriptBridge,
27
+ }
@@ -124,6 +124,8 @@ export abstract class DeviceBase<
124
124
  private bindPreventDefaultEvents(rootElement: HTMLElement) {
125
125
  // prevent default to focus the next focusable element of event target
126
126
  bindPreventDefaultEvent(rootElement, 'keydown');
127
+ // prevent default not to lose focus (Seen on Android TV Bridge)
128
+ bindPreventDefaultEvent(rootElement, 'keyup');
127
129
  // prevent default to focus the nearest focusable ancestor of event target
128
130
  bindPreventDefaultEvent(rootElement, 'mousedown');
129
131
  }
@@ -1,6 +1,7 @@
1
1
  .toast-service-root {
2
2
  position: absolute;
3
3
  left: 0;
4
+ right: 0;
4
5
  top: 0;
5
6
  width: 0;
6
7
  height: 0;