@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 +2 -1
- package/packages/device/src/driver/index.android.tv.ts +1 -0
- package/packages/device/src/resolver/resolver.ts +6 -0
- package/packages/driver-androidtv/src/DeviceAndroidTV.ts +179 -0
- package/packages/driver-androidtv/src/__mocks__/javaScriptBridge.ts +12 -0
- package/packages/driver-androidtv/src/formatUserAgent.ts +11 -0
- package/packages/driver-androidtv/src/index.ts +1 -0
- package/packages/driver-androidtv/src/keymap.ts +9 -0
- package/packages/driver-androidtv/src/types.ts +27 -0
- package/packages/driver-base/src/DeviceBase.ts +2 -0
- package/packages/toast/src/ToastService.scss +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@24i/bigscreen-sdk",
|
|
3
|
-
"version": "1.0.5-alpha.
|
|
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,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
|
}
|