@24i/bigscreen-sdk 1.0.4 → 1.0.5-4.alpha-2832
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/README.md +2 -3
- package/ci/is_ci_job_skippable.sh +153 -0
- package/package.json +55 -34
- package/packages/adobe-heartbeat/src/AdobeHeartbeat.ts +9 -9
- package/packages/analytics/README.md +8 -0
- package/packages/analytics/src/A.ts +1 -0
- package/packages/analytics/src/Analytics.ts +1 -0
- package/packages/analytics/src/analyticsOnScroll.ts +1 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/ConsoleAnalytics.ts +1 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/index.ts +1 -0
- package/packages/analytics/src/clients/GoogleAnalytics/GoogleAnalytics.ts +196 -0
- package/packages/analytics/src/clients/GoogleAnalytics/constants.ts +126 -0
- package/packages/analytics/src/clients/GoogleAnalytics/getUrl.ts +17 -0
- package/packages/analytics/src/clients/GoogleAnalytics/index.ts +2 -0
- package/packages/analytics/src/clients/GoogleAnalytics/interface.ts +82 -0
- package/packages/analytics/src/clients/GoogleAnalytics/mapPayload.ts +51 -0
- package/packages/analytics/src/clients/GoogleAnalytics/prepareBody.ts +14 -0
- package/packages/analytics/src/clients/TealiumAnalytics/TealiumAnalytics.ts +181 -0
- package/packages/analytics/src/clients/TealiumAnalytics/constants.ts +106 -0
- package/packages/analytics/src/clients/TealiumAnalytics/findForLanguage.ts +9 -0
- package/packages/analytics/src/clients/TealiumAnalytics/index.ts +4 -0
- package/packages/analytics/src/clients/TealiumAnalytics/interface.ts +35 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/__mocks__/mediaPayload.ts +72 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/helper.ts +36 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppError.ts +13 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppOpen.ts +13 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteAdd.ts +11 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteRemove.ts +11 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerClose.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerOpen.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSceneView.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearch.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchFailed.ts +8 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchSuccess.ts +8 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoPause.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoProgress.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoResume.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStart.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStop.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/types.ts +161 -0
- package/packages/analytics/src/clients/TwentyFourIQ/TwentyFourIQClient.ts +107 -0
- package/packages/analytics/src/clients/TwentyFourIQ/constants.ts +111 -0
- package/packages/analytics/src/clients/TwentyFourIQ/helper.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/index.ts +2 -0
- package/packages/analytics/src/clients/TwentyFourIQ/interface.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapAdEvent.ts +20 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBase.ts +24 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBuffering.ts +15 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerClose.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerOpen.ts +17 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapSceneView.ts +15 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapScroll.ts +17 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoComplete.ts +22 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoPause.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoProgress.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStart.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStop.ts +32 -0
- package/packages/analytics/src/clients/TwentyFourIQ/types.ts +132 -0
- package/packages/analytics/src/constants.ts +1 -0
- package/packages/analytics/src/index.ts +3 -0
- package/packages/analytics/src/interface.ts +1 -0
- package/packages/analytics/src/utils/generateSessionId.ts +8 -0
- package/packages/async-image/src/AsyncImage.tsx +15 -10
- package/packages/developer-tools/PlayerDebugWindow/README.md +1 -1
- package/packages/developer-tools/src/DeveloperConsole/DeveloperConsole.tsx +1 -0
- package/packages/developer-tools/src/DeveloperToolsService/DeveloperToolsList.tsx +11 -0
- package/packages/developer-tools/src/PlayerDebugWindow/PlayerDebugWindow.tsx +5 -5
- package/packages/developer-tools/src/PlayerDebugWindow/constants.ts +15 -0
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfo.tsx +2 -0
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoDetail.tsx +2 -1
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoProvider.ts +57 -5
- package/packages/developer-tools/src/TechnicalInfo/__mocks__/Device.ts +12 -0
- package/packages/developer-tools/src/TechnicalInfo/translations.ts +8 -0
- package/packages/device/src/driver/index.android.tv.ts +1 -0
- package/packages/device/src/driver/index.firetv.ts +1 -0
- package/packages/device/src/driver/index.smartcast.tv.ts +1 -0
- package/packages/device/src/getKeyDigit.ts +2 -2
- package/packages/device/src/resolver/resolver.ts +19 -0
- package/packages/digital-clock/src/DigitalClock.tsx +15 -4
- package/packages/driver-androidtv/src/DeviceAndroidTV.ts +262 -0
- package/packages/driver-androidtv/src/__mocks__/javaScriptBridge.ts +45 -0
- package/packages/driver-androidtv/src/formatUserAgent.ts +11 -0
- package/packages/driver-androidtv/src/index.ts +2 -0
- package/packages/driver-androidtv/src/keymap.ts +27 -0
- package/packages/driver-androidtv/src/types.ts +155 -0
- package/packages/driver-base/src/DeviceBase.ts +73 -2
- package/packages/driver-base/src/KeyMap/Key.ts +8 -1
- package/packages/driver-base/src/KeyMap/KeyMap.ts +4 -0
- package/packages/driver-base/src/KeyMap/interface.ts +1 -0
- package/packages/driver-base/src/KeyMap/overrideValues.ts +2 -1
- package/packages/driver-base/src/__mocks__/DeviceBase.ts +24 -0
- package/packages/driver-base/src/__mocks__/keyMap.ts +1 -0
- package/packages/driver-base/src/index.ts +3 -0
- package/packages/driver-base/src/types/AdInfo.ts +5 -0
- package/packages/driver-base/src/types/DeviceEvent.ts +2 -0
- package/packages/driver-base/src/types/InAppPurchase.ts +20 -0
- package/packages/driver-base/src/types/KeycodeKeyMap.ts +1 -0
- package/packages/driver-browser/src/DeviceBrowser.ts +26 -0
- package/packages/driver-browser/src/keymap.ts +8 -0
- package/packages/driver-entone/src/DeviceEntone.ts +31 -1
- package/packages/driver-entone/src/keymap.ts +1 -0
- package/packages/driver-firetv/src/DeviceFireTV.ts +86 -0
- package/packages/driver-firetv/src/__mocks__/javaScriptBridge.ts +45 -0
- package/packages/driver-firetv/src/index.ts +1 -0
- package/packages/driver-firetv/src/types.ts +1 -0
- package/packages/driver-hbbtv/src/DeviceHbbTV.ts +26 -0
- package/packages/driver-kreatv/src/DeviceKreaTV.ts +26 -0
- package/packages/driver-saphi/src/DeviceSaphi.ts +26 -0
- package/packages/driver-smartcast/src/DeviceSmartCast.ts +380 -0
- package/packages/driver-smartcast/src/__mocks__/api.ts +69 -0
- package/packages/driver-smartcast/src/index.ts +1 -0
- package/packages/driver-smartcast/src/keymap.ts +9 -0
- package/packages/driver-smartcast/src/types.ts +102 -0
- package/packages/driver-tizen/src/DeviceTizen.ts +121 -7
- package/packages/driver-tizen/src/ITizen.ts +15116 -202
- package/packages/driver-tizen/src/IWebapis.ts +8643 -87
- package/packages/driver-tizen/src/TizenKeys.ts +4 -2
- package/packages/driver-tizen/src/__mocks__/tizen.ts +7 -8
- package/packages/driver-tizen/src/constants.ts +1 -195
- package/packages/driver-vidaa/src/DeviceVidaa.ts +29 -2
- package/packages/driver-vidaa/src/__mocks__/vidaa.ts +1 -1
- package/packages/driver-vidaa/src/keymap.ts +2 -0
- package/packages/driver-webos/src/DeviceWebos.ts +55 -0
- package/packages/driver-webos/src/__mocks__/webos.ts +33 -0
- package/packages/driver-webos/src/constants.ts +1 -0
- package/packages/driver-webos/src/keymap.ts +2 -1
- package/packages/driver-webos/src/types.ts +30 -0
- package/packages/driver-xbox/src/DeviceXbox.ts +30 -1
- package/packages/driver-xbox/src/keymap.ts +1 -1
- package/packages/epg/README.md +3 -1
- package/packages/epg/src/v2/Cell.tsx +16 -2
- package/packages/epg/src/v2/DataManager.ts +112 -41
- package/packages/epg/src/v2/DatePicker.tsx +9 -3
- package/packages/epg/src/v2/DateToast/DateToast.tsx +12 -9
- package/packages/epg/src/v2/Day.tsx +6 -3
- package/packages/epg/src/v2/Epg.tsx +5 -5
- package/packages/epg/src/v2/MockGenerator/generator.ts +3 -2
- package/packages/epg/src/v2/ProgramInfo/utils.ts +4 -3
- package/packages/epg/src/v2/Row.tsx +3 -1
- package/packages/epg/src/v2/TimelineSection.tsx +4 -1
- package/packages/epg/src/v2/basic/CellsManager.tsx +7 -2
- package/packages/epg/src/v2/basic/RowsManager.tsx +3 -1
- package/packages/epg/src/v2/interface.ts +13 -0
- package/packages/events-manager/src/EventsManager.ts +1 -56
- package/packages/focus/README.md +33 -0
- package/packages/focus/src/IFocusable.ts +1 -0
- package/packages/focus/src/Layout/Base.tsx +41 -6
- package/packages/focus/src/Layout/Matrix.tsx +51 -19
- package/packages/focus/src/focusFirstExisting.ts +7 -1
- package/packages/focus/src/hasFocus.ts +36 -0
- package/packages/focus/src/index.ts +2 -1
- package/packages/gallup/src/Gallup.ts +3 -3
- package/packages/grid/src/Base/Base.tsx +15 -10
- package/packages/grid/src/FirstOnlyGrid/FirstOnlyGrid.tsx +4 -2
- package/packages/grid/src/UnifiedGridController/UnifiedGridController.ts +6 -6
- package/packages/icon/src/Icon.tsx +27 -5
- package/packages/input/README.md +1 -1
- package/packages/input/src/Input.tsx +10 -10
- package/packages/interactable/README.md +2 -1
- package/packages/interactable/src/Interactable.tsx +9 -3
- package/packages/interactable/src/interface.ts +1 -0
- package/packages/jsx/src/index.ts +1 -1
- package/packages/jsx/src/test-utils/index.ts +1 -0
- package/packages/jsx/src/test-utils/keyup.ts +27 -0
- package/packages/keyboard/README.md +2 -0
- package/packages/keyboard/src/Backdrop/Backdrop.scss +2 -0
- package/packages/keyboard/src/KeyboardBase.tsx +16 -4
- package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.scss +10 -0
- package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.tsx +128 -142
- package/packages/keyboard/src/WhitelabelKeyboard/WhitelabelStyles/whitelabel.scss +4 -0
- package/packages/keyboard/src/WhitelabelKeyboard/_sizes.1080.scss +1 -0
- package/packages/keyboard/src/WhitelabelKeyboard/_sizes.scss +1 -0
- package/packages/keyboard/src/WhitelabelKeyboard/icons/key_language.svg +20 -0
- package/packages/keyboard/src/WhitelabelKeyboard/index.ts +1 -1
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/arabic.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/burmese.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/dari.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/hebrew.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/index.ts +15 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/korean.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/latin.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/pashto.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/persian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/russian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/spanish.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/special.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/tibetan.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/turkish.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/ukrainian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/urdu.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/types.ts +22 -2
- package/packages/keyboard/src/types/index.ts +1 -1
- package/packages/keyboard/src/utils/caret.ts +5 -8
- package/packages/keyboard/src/utils/input.ts +5 -6
- package/packages/keyboard/src/utils/setInputSelectionRange.ts +10 -0
- package/packages/l10n/README.md +18 -0
- package/packages/l10n/src/date/common.ts +18 -6
- package/packages/l10n/src/date/cs.ts +2 -8
- package/packages/l10n/src/date/de.ts +97 -0
- package/packages/l10n/src/date/en-001.ts +3 -3
- package/packages/l10n/src/date/en-common.ts +5 -4
- package/packages/l10n/src/date/en-us.ts +3 -3
- package/packages/l10n/src/date/es.ts +71 -0
- package/packages/l10n/src/date/fr.ts +94 -0
- package/packages/l10n/src/date/he.ts +101 -0
- package/packages/l10n/src/date/iso.ts +12 -13
- package/packages/l10n/src/date/types.ts +9 -0
- package/packages/l10n/src/l10n.ts +61 -3
- package/packages/list/src/Base/Base.tsx +19 -9
- package/packages/list/src/Base/interface.ts +2 -2
- package/packages/list/src/BasicList/BasicList.tsx +7 -7
- package/packages/list/src/CenteredList/CenteredList.tsx +2 -2
- package/packages/list/src/CenteredList/controller.ts +0 -1
- package/packages/list/src/EdgeOffsetList/EdgeOffsetList.tsx +10 -10
- package/packages/list/src/FirstOnlyList/FirstOnlyList.tsx +2 -2
- package/packages/list/src/FirstOnlyVariedList/FirstOnlyVariedList.tsx +2 -2
- package/packages/list/src/FixedToEndList/FixedToEndList.tsx +2 -2
- package/packages/list/src/UnifiedListController/UnifiedListController.ts +6 -2
- package/packages/list/src/interface.ts +2 -2
- package/packages/logger/src/loggers/ConsoleLogger/ConsoleLogger.ts +7 -1
- package/packages/logger/src/loggers/SentryLogger/Sentry.ts +1 -0
- package/packages/logger/src/loggers/SentryLogger/SentryLogger.ts +5 -3
- package/packages/menu/src/MenuAndContentContainer/MenuAndContentContainer.tsx +31 -3
- package/packages/menu/src/MenuAndContentContainer/interface.ts +8 -0
- package/packages/modal-service/README.md +4 -1
- package/packages/modal-service/src/ModalService.tsx +29 -5
- package/packages/perf-utils/README.md +1 -120
- package/packages/perf-utils/src/array/filter.ts +1 -54
- package/packages/perf-utils/src/array/find.ts +1 -43
- package/packages/perf-utils/src/array/findIndex.ts +1 -43
- package/packages/perf-utils/src/array/forEach.ts +1 -48
- package/packages/perf-utils/src/array/includes.ts +1 -41
- package/packages/perf-utils/src/array/includesNaN.ts +1 -32
- package/packages/perf-utils/src/array/index.ts +1 -7
- package/packages/perf-utils/src/array/map.ts +1 -52
- package/packages/player-ui/README.md +1 -1
- package/packages/player-ui/src/CurrentTime.tsx +2 -2
- package/packages/player-ui/src/Duration.tsx +2 -2
- package/packages/player-ui/src/PauseButton.tsx +8 -0
- package/packages/player-ui/src/PlayerInteractable.tsx +1 -0
- package/packages/player-ui/src/PlayerTime.tsx +3 -1
- package/packages/player-ui/src/PlayerUI.tsx +68 -35
- package/packages/player-ui/src/RemainingTime.tsx +2 -2
- package/packages/player-ui/src/Seekbar.tsx +110 -18
- package/packages/player-ui/src/Seeking.ts +57 -16
- package/packages/player-ui/src/Subtitles.tsx +2 -2
- package/packages/player-ui/src/index.ts +1 -0
- package/packages/player-ui/src/mocks.ts +32 -8
- package/packages/player-ui/src/timeUtils.ts +3 -3
- package/packages/player-ui/src/types.ts +9 -3
- package/packages/router/README.md +1 -0
- package/packages/router/src/Route.tsx +61 -27
- package/packages/router/src/Router.tsx +63 -14
- package/packages/router/src/history.ts +8 -1
- package/packages/router/src/index.ts +1 -1
- package/packages/router/src/utils.ts +9 -4
- package/packages/sass-utils/src/linear-gradient.scss +9 -4
- package/packages/sass-utils/src/scale.1080.scss +3 -1
- package/packages/sass-utils/src/scale.720.scss +1 -1
- package/packages/time/README.md +4 -1
- package/packages/time/src/Time.ts +35 -13
- package/packages/time/src/adapters/24iMediaTimeApi.ts +47 -0
- package/packages/time/src/constants.ts +1 -0
- package/packages/time/src/services/24iMediaTimeApi/24iMediaTimeApi.ts +43 -0
- package/packages/time/src/services/24iMediaTimeApi/index.ts +6 -0
- package/packages/toast/src/ToastService.scss +1 -0
- package/packages/toast/src/ToastService.tsx +16 -5
- package/packages/types-bigscreen-jsx/README.md +5 -4
- package/packages/types-bigscreen-jsx/index.d.ts +72 -67
- package/packages/utils/README.md +27 -0
- package/packages/utils/src/elementUtils.ts +25 -0
- package/packages/utils/src/forceReflow.ts +14 -0
- package/packages/utils/src/index.ts +8 -0
- package/packages/utils/src/keyPress/index.ts +6 -0
- package/packages/utils/src/keyPress/keyPressSimulator.ts +74 -0
- package/packages/utils/src/keyPress/simulateKeyPress.ts +25 -0
- package/packages/utils/src/scaledImage.ts +6 -3
- package/packages/utils/src/textUtils.ts +46 -14
- package/packages/utils/src/wait.ts +3 -1
- package/packages/utils/src/xhr/xhrSend.ts +3 -1
- package/packages/utils/src/xhr/xhrSendRetry.ts +3 -1
- package/packages/zapping/src/ChannelZapping.ts +9 -0
- package/packages/zapping/src/Zapping.tsx +10 -0
- package/utils/release/release.ts +156 -0
- package/packages/driver-tizen/src/types.ts +0 -14
- package/packages/focus/src/Layout/__test__/Base.spec.ts +0 -180
- package/packages/focus/src/Layout/__test__/Horizontal.spec.ts +0 -94
- package/packages/focus/src/Layout/__test__/Matrix.spec.ts +0 -261
- package/packages/focus/src/Layout/__test__/Vertical.spec.ts +0 -46
- package/packages/focus/src/Layout/__test__/isRtl.spec.ts +0 -23
- package/packages/focus/src/Layout/__test__/shared.ts +0 -19
- package/packages/keyboard/src/WhitelabelKeyboard/focusMatrix.ts +0 -19
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeviceBase,
|
|
3
|
+
ConnectionType,
|
|
4
|
+
ScreenSaverStatus,
|
|
5
|
+
VolumeRange,
|
|
6
|
+
IAPSuccessPayload,
|
|
7
|
+
IAPPurchaseProductData,
|
|
8
|
+
} from '@24i/bigscreen-sdk/driver-base';
|
|
9
|
+
import { IJavaScriptBridge, DeviceInfo } from './types';
|
|
10
|
+
import { getFirmware } from './formatUserAgent';
|
|
11
|
+
import { getKeyMap, AndroidKeyMap } from './keymap';
|
|
12
|
+
|
|
13
|
+
interface CustomKeyboardEvent extends KeyboardEvent {
|
|
14
|
+
/** Flag indicating that the driver has already re-emitted this event. */
|
|
15
|
+
bigscreenSdkRelaunched?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare global {
|
|
19
|
+
interface Window extends IJavaScriptBridge {}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Android TV driver implementing API of Android TV Bridge.
|
|
24
|
+
*
|
|
25
|
+
* See https://github.com/24i/prd-smart-ott-androidtv
|
|
26
|
+
*/
|
|
27
|
+
export class DeviceAndroidTV extends DeviceBase {
|
|
28
|
+
keyMap = getKeyMap();
|
|
29
|
+
|
|
30
|
+
deviceInfo = window.JavaScriptBridge.bridgeJavaScriptToAndroid_GetDeviceInfo();
|
|
31
|
+
|
|
32
|
+
platformInfo: DeviceInfo = this.deviceInfo ? JSON.parse(this.deviceInfo) : '';
|
|
33
|
+
|
|
34
|
+
firmware = getFirmware(navigator.userAgent);
|
|
35
|
+
|
|
36
|
+
async initDevice(): Promise<void> {
|
|
37
|
+
this.initKeydownListener();
|
|
38
|
+
this.initKeyupListener();
|
|
39
|
+
this.initNetworkChangeListener();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
initKeydownListener() {
|
|
43
|
+
window.addEventListener('keydown', this.relaunchKeyEvent, true);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
initKeyupListener() {
|
|
47
|
+
window.addEventListener('keyup', this.relaunchKeyEvent, true);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handles keydown/up events for the BACK, FF, REW, STOP, PLAY key which are
|
|
52
|
+
* dispatched on the document from the Android TV Bridge. We must catch them
|
|
53
|
+
* and re-emit them properly on the active (focused) element in the DOM tree.
|
|
54
|
+
* @param event keyboard event
|
|
55
|
+
*/
|
|
56
|
+
// eslint-disable-next-line complexity
|
|
57
|
+
relaunchKeyEvent = (event: CustomKeyboardEvent) => {
|
|
58
|
+
if (event.bigscreenSdkRelaunched) { // prevent to relaunch event in loop
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const { key } = event;
|
|
63
|
+
let { keyCode } = event;
|
|
64
|
+
|
|
65
|
+
// KeyCodes collisions for some key sent from Android wrapper or JavaScript (webView)
|
|
66
|
+
if (
|
|
67
|
+
key === 'u' // keyCode 85, same like PLAYPAUSE
|
|
68
|
+
|| key === 'v' // keyCode 86, same like STOP
|
|
69
|
+
|| key === 'y' // keyCode 89, same like REW
|
|
70
|
+
|| key === 'z' // keyCode 90, same like FF
|
|
71
|
+
) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Remap KeyCode by its key value.
|
|
77
|
+
* On Android all colors keys and some others coming with "0" keyCode.
|
|
78
|
+
*/
|
|
79
|
+
if (key === 'ColorF0Red') keyCode = this.keyMap.RED;
|
|
80
|
+
if (key === 'ColorF1Green') keyCode = this.keyMap.GREEN;
|
|
81
|
+
if (key === 'ColorF2Yellow') keyCode = this.keyMap.YELLOW;
|
|
82
|
+
if (key === 'ColorF3Blue') keyCode = this.keyMap.BLUE;
|
|
83
|
+
if (key === 'ClosedCaptionToggle') keyCode = this.keyMap.SUBTITLES;
|
|
84
|
+
if (keyCode === AndroidKeyMap.STOP) keyCode = this.keyMap.STOP;
|
|
85
|
+
if (keyCode === AndroidKeyMap.PAUSE) keyCode = this.keyMap.PAUSE;
|
|
86
|
+
|
|
87
|
+
if (keyCode === this.keyMap.BACK
|
|
88
|
+
|| keyCode === this.keyMap.STOP
|
|
89
|
+
|| keyCode === this.keyMap.FF
|
|
90
|
+
|| keyCode === this.keyMap.REW
|
|
91
|
+
|| keyCode === this.keyMap.PLAYPAUSE
|
|
92
|
+
|| keyCode === this.keyMap.PLAY
|
|
93
|
+
|| keyCode === this.keyMap.RED
|
|
94
|
+
|| keyCode === this.keyMap.GREEN
|
|
95
|
+
|| keyCode === this.keyMap.YELLOW
|
|
96
|
+
|| keyCode === this.keyMap.BLUE
|
|
97
|
+
|| keyCode === this.keyMap.SUBTITLES
|
|
98
|
+
) {
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
event.stopImmediatePropagation();
|
|
101
|
+
const newEvent = new KeyboardEvent(event.type, {
|
|
102
|
+
keyCode, bubbles: true, cancelable: true, composed: true,
|
|
103
|
+
}) as CustomKeyboardEvent;
|
|
104
|
+
newEvent.bigscreenSdkRelaunched = true;
|
|
105
|
+
document.activeElement?.dispatchEvent(newEvent);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
initNetworkChangeListener() {
|
|
110
|
+
window.addEventListener('online', () => {
|
|
111
|
+
this.triggerEvent('networkchange', { isConnected: true });
|
|
112
|
+
});
|
|
113
|
+
window.addEventListener('offline', () => {
|
|
114
|
+
this.triggerEvent('networkchange', { isConnected: false });
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
reboot(): void {
|
|
119
|
+
let rootPath = '';
|
|
120
|
+
const splitUrl = window.location.href.split('#');
|
|
121
|
+
if (splitUrl.length > 1) rootPath = splitUrl[0];
|
|
122
|
+
window.location.href = rootPath;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
exit(): void {
|
|
126
|
+
window.JavaScriptBridge.bridgeJavaScriptToAndroid_Back();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async getManufacturerName(): Promise<string> {
|
|
130
|
+
return this.platformInfo.deviceBrand || '';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async getPlatformName(): Promise<string> {
|
|
134
|
+
return 'AndroidTV';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async getPlatformVersion(): Promise<string> {
|
|
138
|
+
return this.platformInfo.osVersion || '';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async getDeviceName(): Promise<string> {
|
|
142
|
+
const modelName = await this.getModelName();
|
|
143
|
+
const manufacturerName = await this.getManufacturerName();
|
|
144
|
+
return `AndroidTV ${manufacturerName} ${modelName}`.trim();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async getModelName(): Promise<string> {
|
|
148
|
+
return this.platformInfo.deviceModel || '';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async getFirmware(): Promise<string> {
|
|
152
|
+
return this.firmware || '';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async is4KSupported(): Promise<boolean> {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async is8KSupported(): Promise<boolean> {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async getUuid(): Promise<string> {
|
|
164
|
+
return this.getBaseUuid();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async getAdInfo() {
|
|
168
|
+
let adId = null;
|
|
169
|
+
let latEnabled = null;
|
|
170
|
+
const type = 'gaid';
|
|
171
|
+
try {
|
|
172
|
+
adId = window.JavaScriptBridge.bridgeJavaScriptToAndroid_GetAdId() ?? null;
|
|
173
|
+
latEnabled = window.JavaScriptBridge.bridgeJavaScriptToAndroid_GetLimitAdTracking()
|
|
174
|
+
?? true;
|
|
175
|
+
} catch (e) {
|
|
176
|
+
latEnabled = true;
|
|
177
|
+
console.error('[DeviceAndroidTV] Failed to getAdInfo', e);
|
|
178
|
+
}
|
|
179
|
+
return { adId, type, latEnabled };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async getOsLanguage() {
|
|
183
|
+
try {
|
|
184
|
+
return window.JavaScriptBridge.bridgeJavaScriptToAndroid_GetOsLanguage() || '';
|
|
185
|
+
} catch (e) {
|
|
186
|
+
console.error('[DeviceAndroidTV] Failed to getOsLanguage', e);
|
|
187
|
+
return '';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async getVolume(): Promise<number> {
|
|
192
|
+
return VolumeRange.UNSUPPORTED;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async getWrapperVersion(): Promise<string> {
|
|
196
|
+
return this.platformInfo.appVersion;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
200
|
+
async setVolume(volumePercentage: number): Promise<void> {
|
|
201
|
+
// not supported on AndroidTV platform
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
205
|
+
async mute(mute: boolean): Promise<void> {
|
|
206
|
+
// not supported on AndroidTV platform
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async isMute(): Promise<boolean> {
|
|
210
|
+
// not supported on AndroidTV platform
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async getScreenSaver(): Promise<ScreenSaverStatus> {
|
|
215
|
+
// not supported on AndroidTV platform
|
|
216
|
+
return { enabled: false };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
220
|
+
async setScreenSaver(status: ScreenSaverStatus): Promise<void> {
|
|
221
|
+
// not supported on AndroidTV platform
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
225
|
+
async setUserAgent(userAgent: string): Promise<boolean> {
|
|
226
|
+
// not supported on AndroidTV platform
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async isNetworkConnected(): Promise<boolean> {
|
|
231
|
+
return window.navigator.onLine;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async getConnectionType(): Promise<ConnectionType> {
|
|
235
|
+
// not supported on AndroidTV platform
|
|
236
|
+
return 'unknown';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async getLocalIP(): Promise<string> {
|
|
240
|
+
const ipv4RegExp = /\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/;
|
|
241
|
+
const ip = this.platformInfo.ipLocal.toString().match(ipv4RegExp);
|
|
242
|
+
if (ip) return ip.toString();
|
|
243
|
+
return '';
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async getMacAddress(): Promise<string> {
|
|
247
|
+
// not supported on AndroidTV platform
|
|
248
|
+
return '';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
252
|
+
async purchaseProduct(data: IAPPurchaseProductData): Promise<IAPSuccessPayload> {
|
|
253
|
+
// not supported
|
|
254
|
+
throw new Error('Not supported');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
258
|
+
async cancelSubscription(data: IAPPurchaseProductData): Promise<void> {
|
|
259
|
+
// not supported
|
|
260
|
+
throw new Error('Not supported');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { IJavaScriptBridge } from '../types';
|
|
2
|
+
|
|
3
|
+
export const mockJavaScriptBridge: IJavaScriptBridge = {
|
|
4
|
+
JavaScriptBridge: {
|
|
5
|
+
bridgeJavaScriptToAndroid_GetDeviceInfo: () => (
|
|
6
|
+
JSON.stringify({
|
|
7
|
+
deviceBrand: 'Sony',
|
|
8
|
+
deviceModel: 'BRAVIA 4K 2015',
|
|
9
|
+
osVersion: '8.0.0',
|
|
10
|
+
appVersion: '0.0.1',
|
|
11
|
+
appFlavor: 'appstage-bigscreen',
|
|
12
|
+
drmKeySystems: '["W3C Clear Key", "Google Widevine"]',
|
|
13
|
+
ipLocal: '127.0.0.1',
|
|
14
|
+
})
|
|
15
|
+
),
|
|
16
|
+
bridgeJavaScriptToAndroid_GetAdId: () => 'gaid-id',
|
|
17
|
+
bridgeJavaScriptToAndroid_GetLimitAdTracking: () => false,
|
|
18
|
+
bridgeJavaScriptToAndroid_GetOsLanguage: () => '',
|
|
19
|
+
bridgeJavaScriptToAndroid_GetMediaInfo: () => '{}',
|
|
20
|
+
bridgeJavaScriptToAndroid_Back: () => {},
|
|
21
|
+
bridgeJavaScriptToAndroid_ReloadPlayer: () => {},
|
|
22
|
+
bridgeJavaScriptToAndroid_StopVideo: () => {},
|
|
23
|
+
bridgeJavaScriptToAndroid_FullScreenVideo: () => {},
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
25
|
+
bridgeJavaScriptToAndroid_SetVideoPath: (url: string) => {},
|
|
26
|
+
bridgeJavaScriptToAndroid_IsPlaying: () => true,
|
|
27
|
+
bridgeJavaScriptToAndroid_PauseVideo: () => {},
|
|
28
|
+
bridgeJavaScriptToAndroid_PlayVideo: () => {},
|
|
29
|
+
bridgeJavaScriptToAndroid_IsLive: () => false,
|
|
30
|
+
bridgeJavaScriptToAndroid_GetCurrentTime: () => Date.now(),
|
|
31
|
+
bridgeJavaScriptToAndroid_GetTotalTime: () => Date.now(),
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
33
|
+
bridgeJavaScriptToAndroid_SeekTo: (milliseconds: number) => {},
|
|
34
|
+
bridgeJavaScriptToAndroid_getCurrentSubtitleTrack: () => '{}',
|
|
35
|
+
bridgeJavaScriptToAndroid_getCurrentAudioTrack: () => '{}',
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
37
|
+
bridgeJavaScriptToAndroid_SetTrack: (track: string) => {},
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
39
|
+
bridgeJavaScriptToAndroid_SetAudioTrack: (track: string) => {},
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
41
|
+
bridgeReceiptAmazonIAPValidation: (sku: string) => {},
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
43
|
+
bridgeReceiptAmazonIAPValidated: (receiptId: string) => {},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -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,27 @@
|
|
|
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
|
+
STOP: { keyCode: 86 },
|
|
8
|
+
FF: { keyCode: 90 },
|
|
9
|
+
REW: { keyCode: 89 },
|
|
10
|
+
PLAY: { keyCode: 126 },
|
|
11
|
+
PAUSE: { keyCode: 127 },
|
|
12
|
+
PLAYPAUSE: { keyCode: 85 },
|
|
13
|
+
SUBTITLES: { keyCode: 175 },
|
|
14
|
+
});
|
|
15
|
+
return KeyMap.generateKeyCodeKeyMap();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* For the specific AndroidTV devices like Sony Bravia or Nvidia Shield
|
|
20
|
+
* there are different KeyCodes for some buttons than on other platforms.
|
|
21
|
+
* In that case we need to re-map this specific KeyCodes to the
|
|
22
|
+
* same values as we using in generic KeyMap list for the AndroidTV.
|
|
23
|
+
*/
|
|
24
|
+
export const AndroidKeyMap = {
|
|
25
|
+
STOP: 178,
|
|
26
|
+
PAUSE: 85,
|
|
27
|
+
};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
interface JavaScriptBridge {
|
|
2
|
+
/**
|
|
3
|
+
* It returns a JSON string with device info.
|
|
4
|
+
* @return JSON string with the information about the device brand, model and Android version.
|
|
5
|
+
* Ex. '{"deviceBrand": "Sony", "deviceModel": "BRAVIA 4K 2015", "osVersion": "7.0",
|
|
6
|
+
* "appFlavor": "appstage-bigscreen", "drmKeySystems": ["Widewine", "W3C ClearKey"],
|
|
7
|
+
* "ipLocal": "fe80::475:3045:2928:3a32%wlan0127.0.0.1", "appVersion": '0.0.1' }'
|
|
8
|
+
*/
|
|
9
|
+
bridgeJavaScriptToAndroid_GetDeviceInfo: () => string,
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* It returns advertising id.
|
|
13
|
+
* @return Advertising id or null if not available.
|
|
14
|
+
*/
|
|
15
|
+
bridgeJavaScriptToAndroid_GetAdId: () => string | null,
|
|
16
|
+
/**
|
|
17
|
+
* It returns limit ad tracking status
|
|
18
|
+
* @return true if limit ad tracking is enabled, false if not and null if not available.
|
|
19
|
+
*/
|
|
20
|
+
bridgeJavaScriptToAndroid_GetLimitAdTracking: () => boolean | null,
|
|
21
|
+
/**
|
|
22
|
+
* It returns the language of the OS.
|
|
23
|
+
* @return Language of the OS. Ex. "en"
|
|
24
|
+
*/
|
|
25
|
+
bridgeJavaScriptToAndroid_GetOsLanguage: () => string,
|
|
26
|
+
/**
|
|
27
|
+
* It returns media info including statistics
|
|
28
|
+
*/
|
|
29
|
+
bridgeJavaScriptToAndroid_GetMediaInfo: () => string;
|
|
30
|
+
/**
|
|
31
|
+
* It simulates a native Android back press.
|
|
32
|
+
*/
|
|
33
|
+
bridgeJavaScriptToAndroid_Back: () => void,
|
|
34
|
+
/**
|
|
35
|
+
* It reloads the video player
|
|
36
|
+
*/
|
|
37
|
+
bridgeJavaScriptToAndroid_ReloadPlayer: () => void;
|
|
38
|
+
/**
|
|
39
|
+
* It simulates a native Android stop button press.
|
|
40
|
+
*/
|
|
41
|
+
bridgeJavaScriptToAndroid_StopVideo: () => void;
|
|
42
|
+
/**
|
|
43
|
+
* It sets the video to fullscreen mode
|
|
44
|
+
*/
|
|
45
|
+
bridgeJavaScriptToAndroid_FullScreenVideo: () => void;
|
|
46
|
+
/**
|
|
47
|
+
* It sets the video url
|
|
48
|
+
*/
|
|
49
|
+
bridgeJavaScriptToAndroid_SetVideoPath: (url: string) => void;
|
|
50
|
+
/**
|
|
51
|
+
* It returns whether the video is playing
|
|
52
|
+
*/
|
|
53
|
+
bridgeJavaScriptToAndroid_IsPlaying: () => boolean;
|
|
54
|
+
/**
|
|
55
|
+
* It pauses the video
|
|
56
|
+
*/
|
|
57
|
+
bridgeJavaScriptToAndroid_PauseVideo: () => void;
|
|
58
|
+
/**
|
|
59
|
+
* It plays the video
|
|
60
|
+
*/
|
|
61
|
+
bridgeJavaScriptToAndroid_PlayVideo: () => void;
|
|
62
|
+
/**
|
|
63
|
+
* It returns whether the video is live
|
|
64
|
+
*/
|
|
65
|
+
bridgeJavaScriptToAndroid_IsLive: () => boolean;
|
|
66
|
+
/**
|
|
67
|
+
* It returns current time of currently played video
|
|
68
|
+
*/
|
|
69
|
+
bridgeJavaScriptToAndroid_GetCurrentTime: () => number;
|
|
70
|
+
/**
|
|
71
|
+
* It returns total duration of the video
|
|
72
|
+
*/
|
|
73
|
+
bridgeJavaScriptToAndroid_GetTotalTime: () => number;
|
|
74
|
+
/**
|
|
75
|
+
* It seeks the video to specified milliseconds
|
|
76
|
+
*/
|
|
77
|
+
bridgeJavaScriptToAndroid_SeekTo: (milliseconds: number) => void;
|
|
78
|
+
/**
|
|
79
|
+
* It returns current text track
|
|
80
|
+
*/
|
|
81
|
+
bridgeJavaScriptToAndroid_getCurrentSubtitleTrack: () => string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* It returns current audio track
|
|
84
|
+
*/
|
|
85
|
+
bridgeJavaScriptToAndroid_getCurrentAudioTrack: () => string | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* It sets text track to be shown.
|
|
88
|
+
*/
|
|
89
|
+
bridgeJavaScriptToAndroid_SetTrack: (track: string) => void;
|
|
90
|
+
/**
|
|
91
|
+
* It sets audio track to be used.
|
|
92
|
+
*/
|
|
93
|
+
bridgeJavaScriptToAndroid_SetAudioTrack: (track: string) => void;
|
|
94
|
+
/**
|
|
95
|
+
* It launch in app purchase.
|
|
96
|
+
*/
|
|
97
|
+
bridgeReceiptAmazonIAPValidation: (sku: string) => void;
|
|
98
|
+
/**
|
|
99
|
+
* It validate purchase.
|
|
100
|
+
*/
|
|
101
|
+
bridgeReceiptAmazonIAPValidated: (receiptId: string) => void;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type DeviceInfo = {
|
|
105
|
+
/**
|
|
106
|
+
* Device brand. Ex. "Sony"
|
|
107
|
+
*/
|
|
108
|
+
deviceBrand: string,
|
|
109
|
+
/**
|
|
110
|
+
* Device model. Ex. "BRAVIA 4K 2015"
|
|
111
|
+
*/
|
|
112
|
+
deviceModel: string,
|
|
113
|
+
/**
|
|
114
|
+
* Android version. Ex. "7.0"
|
|
115
|
+
*/
|
|
116
|
+
osVersion: string,
|
|
117
|
+
/**
|
|
118
|
+
* Android wrapper version. Ex. "0.0.1"
|
|
119
|
+
*/
|
|
120
|
+
appVersion: string,
|
|
121
|
+
/**
|
|
122
|
+
* Android flavor. Ex. "appstage-bigscreen"
|
|
123
|
+
*/
|
|
124
|
+
appFlavor: string,
|
|
125
|
+
/**
|
|
126
|
+
* Underlying player engine name. Ex. "exoplayer"
|
|
127
|
+
*/
|
|
128
|
+
engineName: string,
|
|
129
|
+
/**
|
|
130
|
+
* Version of player engine. Ex. "2.18.1"
|
|
131
|
+
*/
|
|
132
|
+
engineVersion: string,
|
|
133
|
+
/**
|
|
134
|
+
* Android DRM key systems. Ex. ["Widewine", "W3C ClearKey"]
|
|
135
|
+
*/
|
|
136
|
+
drmKeySystems: Array<string>,
|
|
137
|
+
/**
|
|
138
|
+
* Android local IP adress in array Ex. "fe80::475:3045:2928:3a32%wlan0127.0.0.1"
|
|
139
|
+
*/
|
|
140
|
+
ipLocal: string,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export interface IJavaScriptBridge {
|
|
144
|
+
JavaScriptBridge: JavaScriptBridge,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export type IAPSuccessEvent = {
|
|
148
|
+
userId: string;
|
|
149
|
+
receipt: string;
|
|
150
|
+
sku: string;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export type IAPErrorEvent = {
|
|
154
|
+
message: string;
|
|
155
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Storage } from '@24i/bigscreen-sdk/storage';
|
|
2
|
+
import { config } from '@24i/bigscreen-sdk/runtime-config';
|
|
2
3
|
import { generateUuid } from '@24i/bigscreen-sdk/utils/generateUuid';
|
|
3
4
|
import { EventsManager, IEvents, EventMapType } from '@24i/bigscreen-sdk/events-manager';
|
|
4
5
|
import { isRtl } from '@24i/bigscreen-sdk/i18n';
|
|
@@ -7,15 +8,22 @@ import { ScreenSize } from './ScreenSize';
|
|
|
7
8
|
import { VolumeRange } from './VolumeRange';
|
|
8
9
|
import { KeycodeKeyMap } from './types/KeycodeKeyMap';
|
|
9
10
|
import { DeviceEventMap } from './types/DeviceEvent';
|
|
11
|
+
import { AdInfo } from './types/AdInfo';
|
|
10
12
|
import { ScreenSaverStatus } from './types/ScreenSaverStatus';
|
|
11
13
|
import { ExitOptions } from './types/ExitOptions';
|
|
12
14
|
import { inRange } from './utils';
|
|
13
15
|
import { ErrorTemplate } from './errors';
|
|
14
16
|
import { bindPreventDefaultEvent } from './bindPreventDefaultEvent';
|
|
15
|
-
import { LEFT, RIGHT, UP, DOWN, ENTER, BACK } from './KeyMap';
|
|
17
|
+
import { LEFT, RIGHT, UP, DOWN, ENTER, BACK, ESC } from './KeyMap';
|
|
18
|
+
import { IAPPurchaseProductData, IAPSuccessPayload } from './types/InAppPurchase';
|
|
16
19
|
|
|
17
20
|
export const STORAGE_UUID_KEY = '__UUID__';
|
|
18
21
|
|
|
22
|
+
const DEFAULT_POLLING_INTERVAL = 15000;
|
|
23
|
+
const DEFAULT_POLLING_TIMEOUT = 15000;
|
|
24
|
+
|
|
25
|
+
const CHECKED_URL = '//www.google-analytics.com/__utm.gif';
|
|
26
|
+
|
|
19
27
|
export abstract class DeviceBase<
|
|
20
28
|
CustomEventMap extends EventMapType = {},
|
|
21
29
|
EventMap extends EventMapType = DeviceEventMap & CustomEventMap,
|
|
@@ -41,6 +49,14 @@ export abstract class DeviceBase<
|
|
|
41
49
|
|
|
42
50
|
screenSize: ScreenSize = 'unknown';
|
|
43
51
|
|
|
52
|
+
pollingInterval: number = DEFAULT_POLLING_INTERVAL;
|
|
53
|
+
|
|
54
|
+
pollingTimeout: number = DEFAULT_POLLING_TIMEOUT;
|
|
55
|
+
|
|
56
|
+
imageTimeout: number = 0;
|
|
57
|
+
|
|
58
|
+
isOffline: boolean = false;
|
|
59
|
+
|
|
44
60
|
// MARK: Initialization
|
|
45
61
|
|
|
46
62
|
/**
|
|
@@ -52,6 +68,7 @@ export abstract class DeviceBase<
|
|
|
52
68
|
if (!this.isInitialized) {
|
|
53
69
|
this.bindPreventDefaultEvents(rootElement);
|
|
54
70
|
const initializer = await this.internalInit();
|
|
71
|
+
this.checkNetworkConnection();
|
|
55
72
|
this.isInitialized = true;
|
|
56
73
|
return initializer;
|
|
57
74
|
}
|
|
@@ -71,6 +88,46 @@ export abstract class DeviceBase<
|
|
|
71
88
|
return this.initializer;
|
|
72
89
|
}
|
|
73
90
|
|
|
91
|
+
doOnlineCheck = () => {
|
|
92
|
+
const protocol = window.location.protocol === 'http:' ? 'http:' : 'https:';
|
|
93
|
+
const tester = new Image();
|
|
94
|
+
this.imageTimeout = window.setTimeout(() => {
|
|
95
|
+
this.connectionNotFound();
|
|
96
|
+
}, this.pollingTimeout || DEFAULT_POLLING_TIMEOUT);
|
|
97
|
+
tester.onload = this.connectionFound;
|
|
98
|
+
tester.onerror = this.connectionNotFound;
|
|
99
|
+
tester.src = `${protocol}${CHECKED_URL}?ts=${Date.now()}`;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
connectionFound = () => {
|
|
103
|
+
window.clearTimeout(this.imageTimeout);
|
|
104
|
+
if (!this.isOffline) return;
|
|
105
|
+
this.triggerEvent('networkchange',
|
|
106
|
+
{ isConnected: true } as any);
|
|
107
|
+
this.isOffline = false;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
connectionNotFound = () => {
|
|
111
|
+
window.clearTimeout(this.imageTimeout);
|
|
112
|
+
if (this.isOffline) return;
|
|
113
|
+
this.triggerEvent('networkchange',
|
|
114
|
+
{ isConnected: false } as any);
|
|
115
|
+
this.isOffline = true;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
checkNetworkConnection() {
|
|
119
|
+
const networkConfig: any = config.get('network.checkConnection');
|
|
120
|
+
this.pollingInterval = Number(networkConfig?.pollingInterval);
|
|
121
|
+
this.pollingTimeout = Number(networkConfig?.pollingTimeout);
|
|
122
|
+
const enableCheckNetwork: any = Boolean(networkConfig?.enableCheckNetwork) ?? false;
|
|
123
|
+
if (enableCheckNetwork) {
|
|
124
|
+
window.setInterval(
|
|
125
|
+
this.doOnlineCheck,
|
|
126
|
+
this.pollingInterval || DEFAULT_POLLING_INTERVAL,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
74
131
|
// MARK: Interface implemented by individual platform-specific drivers
|
|
75
132
|
|
|
76
133
|
abstract initDevice(): Promise<void>;
|
|
@@ -97,6 +154,10 @@ export abstract class DeviceBase<
|
|
|
97
154
|
|
|
98
155
|
abstract getUuid(): Promise<string>;
|
|
99
156
|
|
|
157
|
+
abstract getAdInfo(): Promise<AdInfo>;
|
|
158
|
+
|
|
159
|
+
abstract getOsLanguage(): Promise<string>;
|
|
160
|
+
|
|
100
161
|
abstract getVolume(): Promise<number>;
|
|
101
162
|
|
|
102
163
|
abstract setVolume(volumePercentage: number): Promise<void>;
|
|
@@ -119,11 +180,17 @@ export abstract class DeviceBase<
|
|
|
119
180
|
|
|
120
181
|
abstract getMacAddress(): Promise<string>;
|
|
121
182
|
|
|
183
|
+
abstract purchaseProduct(data: IAPPurchaseProductData): Promise<IAPSuccessPayload>;
|
|
184
|
+
|
|
185
|
+
abstract cancelSubscription(data: IAPPurchaseProductData): Promise<void>;
|
|
186
|
+
|
|
122
187
|
// MARK: Private functions
|
|
123
188
|
|
|
124
189
|
private bindPreventDefaultEvents(rootElement: HTMLElement) {
|
|
125
190
|
// prevent default to focus the next focusable element of event target
|
|
126
191
|
bindPreventDefaultEvent(rootElement, 'keydown');
|
|
192
|
+
// prevent default not to lose focus (Seen on Android TV Bridge)
|
|
193
|
+
bindPreventDefaultEvent(rootElement, 'keyup');
|
|
127
194
|
// prevent default to focus the nearest focusable ancestor of event target
|
|
128
195
|
bindPreventDefaultEvent(rootElement, 'mousedown');
|
|
129
196
|
}
|
|
@@ -203,7 +270,7 @@ export abstract class DeviceBase<
|
|
|
203
270
|
}
|
|
204
271
|
|
|
205
272
|
isBackOrEscape(event: MouseEvent | KeyboardEvent) {
|
|
206
|
-
return BACK.is(event as KeyboardEvent);
|
|
273
|
+
return BACK.is(event as KeyboardEvent) || ESC.is(event as KeyboardEvent);
|
|
207
274
|
}
|
|
208
275
|
|
|
209
276
|
getDeviceClass() : string {
|
|
@@ -215,4 +282,8 @@ export abstract class DeviceBase<
|
|
|
215
282
|
isMouseUsed() {
|
|
216
283
|
return this.isMouseActive;
|
|
217
284
|
}
|
|
285
|
+
|
|
286
|
+
getResolution() {
|
|
287
|
+
return { width: window.screen?.width, height: window.screen?.height };
|
|
288
|
+
}
|
|
218
289
|
}
|
|
@@ -12,21 +12,25 @@ export class Key {
|
|
|
12
12
|
|
|
13
13
|
alternativeKeyCodes: number[];
|
|
14
14
|
|
|
15
|
+
key: string;
|
|
16
|
+
|
|
15
17
|
constructor({
|
|
16
18
|
id,
|
|
17
19
|
code = '',
|
|
18
20
|
keyCode = 0,
|
|
19
21
|
alternativeCodes = [],
|
|
20
22
|
alternativeKeyCodes = [],
|
|
23
|
+
key = '',
|
|
21
24
|
}: Partial<KeyConfig> = {}) {
|
|
22
25
|
this.id = id!;
|
|
23
26
|
this.code = code;
|
|
24
27
|
this.keyCode = keyCode;
|
|
25
28
|
this.alternativeCodes = alternativeCodes;
|
|
26
29
|
this.alternativeKeyCodes = alternativeKeyCodes;
|
|
30
|
+
this.key = key;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
is({ keyCode, code }: KeyboardEvent) {
|
|
33
|
+
is({ keyCode, code, key }: KeyboardEvent) {
|
|
30
34
|
return Boolean(
|
|
31
35
|
code && ( // empty string code means unknown/invalid --> should not compare
|
|
32
36
|
code === this.code
|
|
@@ -35,6 +39,9 @@ export class Key {
|
|
|
35
39
|
|| keyCode && ( // keyCode 0 means unknown/invalid --> should not compare
|
|
36
40
|
keyCode === this.keyCode
|
|
37
41
|
|| this.alternativeKeyCodes.length && includes(this.alternativeKeyCodes, keyCode)
|
|
42
|
+
)
|
|
43
|
+
|| key && ( // empty string code means unknown/invalid --> should not compare
|
|
44
|
+
key === this.key
|
|
38
45
|
),
|
|
39
46
|
);
|
|
40
47
|
}
|