@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.
Files changed (292) hide show
  1. package/README.md +2 -3
  2. package/ci/is_ci_job_skippable.sh +153 -0
  3. package/package.json +55 -34
  4. package/packages/adobe-heartbeat/src/AdobeHeartbeat.ts +9 -9
  5. package/packages/analytics/README.md +8 -0
  6. package/packages/analytics/src/A.ts +1 -0
  7. package/packages/analytics/src/Analytics.ts +1 -0
  8. package/packages/analytics/src/analyticsOnScroll.ts +1 -0
  9. package/packages/analytics/src/clients/ConsoleAnalytics/ConsoleAnalytics.ts +1 -0
  10. package/packages/analytics/src/clients/ConsoleAnalytics/index.ts +1 -0
  11. package/packages/analytics/src/clients/GoogleAnalytics/GoogleAnalytics.ts +196 -0
  12. package/packages/analytics/src/clients/GoogleAnalytics/constants.ts +126 -0
  13. package/packages/analytics/src/clients/GoogleAnalytics/getUrl.ts +17 -0
  14. package/packages/analytics/src/clients/GoogleAnalytics/index.ts +2 -0
  15. package/packages/analytics/src/clients/GoogleAnalytics/interface.ts +82 -0
  16. package/packages/analytics/src/clients/GoogleAnalytics/mapPayload.ts +51 -0
  17. package/packages/analytics/src/clients/GoogleAnalytics/prepareBody.ts +14 -0
  18. package/packages/analytics/src/clients/TealiumAnalytics/TealiumAnalytics.ts +181 -0
  19. package/packages/analytics/src/clients/TealiumAnalytics/constants.ts +106 -0
  20. package/packages/analytics/src/clients/TealiumAnalytics/findForLanguage.ts +9 -0
  21. package/packages/analytics/src/clients/TealiumAnalytics/index.ts +4 -0
  22. package/packages/analytics/src/clients/TealiumAnalytics/interface.ts +35 -0
  23. package/packages/analytics/src/clients/TealiumAnalytics/mappers/__mocks__/mediaPayload.ts +72 -0
  24. package/packages/analytics/src/clients/TealiumAnalytics/mappers/helper.ts +36 -0
  25. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppError.ts +13 -0
  26. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppOpen.ts +13 -0
  27. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteAdd.ts +11 -0
  28. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteRemove.ts +11 -0
  29. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerClose.ts +15 -0
  30. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerOpen.ts +15 -0
  31. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSceneView.ts +18 -0
  32. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearch.ts +18 -0
  33. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchFailed.ts +8 -0
  34. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchSuccess.ts +8 -0
  35. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoPause.ts +15 -0
  36. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoProgress.ts +18 -0
  37. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoResume.ts +15 -0
  38. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStart.ts +15 -0
  39. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStop.ts +15 -0
  40. package/packages/analytics/src/clients/TealiumAnalytics/types.ts +161 -0
  41. package/packages/analytics/src/clients/TwentyFourIQ/TwentyFourIQClient.ts +107 -0
  42. package/packages/analytics/src/clients/TwentyFourIQ/constants.ts +111 -0
  43. package/packages/analytics/src/clients/TwentyFourIQ/helper.ts +34 -0
  44. package/packages/analytics/src/clients/TwentyFourIQ/index.ts +2 -0
  45. package/packages/analytics/src/clients/TwentyFourIQ/interface.ts +34 -0
  46. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapAdEvent.ts +20 -0
  47. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBase.ts +24 -0
  48. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBuffering.ts +15 -0
  49. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerClose.ts +25 -0
  50. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerOpen.ts +17 -0
  51. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapSceneView.ts +15 -0
  52. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapScroll.ts +17 -0
  53. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoComplete.ts +22 -0
  54. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoPause.ts +25 -0
  55. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoProgress.ts +25 -0
  56. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStart.ts +34 -0
  57. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStop.ts +32 -0
  58. package/packages/analytics/src/clients/TwentyFourIQ/types.ts +132 -0
  59. package/packages/analytics/src/constants.ts +1 -0
  60. package/packages/analytics/src/index.ts +3 -0
  61. package/packages/analytics/src/interface.ts +1 -0
  62. package/packages/analytics/src/utils/generateSessionId.ts +8 -0
  63. package/packages/async-image/src/AsyncImage.tsx +15 -10
  64. package/packages/developer-tools/PlayerDebugWindow/README.md +1 -1
  65. package/packages/developer-tools/src/DeveloperConsole/DeveloperConsole.tsx +1 -0
  66. package/packages/developer-tools/src/DeveloperToolsService/DeveloperToolsList.tsx +11 -0
  67. package/packages/developer-tools/src/PlayerDebugWindow/PlayerDebugWindow.tsx +5 -5
  68. package/packages/developer-tools/src/PlayerDebugWindow/constants.ts +15 -0
  69. package/packages/developer-tools/src/TechnicalInfo/TechnicalInfo.tsx +2 -0
  70. package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoDetail.tsx +2 -1
  71. package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoProvider.ts +57 -5
  72. package/packages/developer-tools/src/TechnicalInfo/__mocks__/Device.ts +12 -0
  73. package/packages/developer-tools/src/TechnicalInfo/translations.ts +8 -0
  74. package/packages/device/src/driver/index.android.tv.ts +1 -0
  75. package/packages/device/src/driver/index.firetv.ts +1 -0
  76. package/packages/device/src/driver/index.smartcast.tv.ts +1 -0
  77. package/packages/device/src/getKeyDigit.ts +2 -2
  78. package/packages/device/src/resolver/resolver.ts +19 -0
  79. package/packages/digital-clock/src/DigitalClock.tsx +15 -4
  80. package/packages/driver-androidtv/src/DeviceAndroidTV.ts +262 -0
  81. package/packages/driver-androidtv/src/__mocks__/javaScriptBridge.ts +45 -0
  82. package/packages/driver-androidtv/src/formatUserAgent.ts +11 -0
  83. package/packages/driver-androidtv/src/index.ts +2 -0
  84. package/packages/driver-androidtv/src/keymap.ts +27 -0
  85. package/packages/driver-androidtv/src/types.ts +155 -0
  86. package/packages/driver-base/src/DeviceBase.ts +73 -2
  87. package/packages/driver-base/src/KeyMap/Key.ts +8 -1
  88. package/packages/driver-base/src/KeyMap/KeyMap.ts +4 -0
  89. package/packages/driver-base/src/KeyMap/interface.ts +1 -0
  90. package/packages/driver-base/src/KeyMap/overrideValues.ts +2 -1
  91. package/packages/driver-base/src/__mocks__/DeviceBase.ts +24 -0
  92. package/packages/driver-base/src/__mocks__/keyMap.ts +1 -0
  93. package/packages/driver-base/src/index.ts +3 -0
  94. package/packages/driver-base/src/types/AdInfo.ts +5 -0
  95. package/packages/driver-base/src/types/DeviceEvent.ts +2 -0
  96. package/packages/driver-base/src/types/InAppPurchase.ts +20 -0
  97. package/packages/driver-base/src/types/KeycodeKeyMap.ts +1 -0
  98. package/packages/driver-browser/src/DeviceBrowser.ts +26 -0
  99. package/packages/driver-browser/src/keymap.ts +8 -0
  100. package/packages/driver-entone/src/DeviceEntone.ts +31 -1
  101. package/packages/driver-entone/src/keymap.ts +1 -0
  102. package/packages/driver-firetv/src/DeviceFireTV.ts +86 -0
  103. package/packages/driver-firetv/src/__mocks__/javaScriptBridge.ts +45 -0
  104. package/packages/driver-firetv/src/index.ts +1 -0
  105. package/packages/driver-firetv/src/types.ts +1 -0
  106. package/packages/driver-hbbtv/src/DeviceHbbTV.ts +26 -0
  107. package/packages/driver-kreatv/src/DeviceKreaTV.ts +26 -0
  108. package/packages/driver-saphi/src/DeviceSaphi.ts +26 -0
  109. package/packages/driver-smartcast/src/DeviceSmartCast.ts +380 -0
  110. package/packages/driver-smartcast/src/__mocks__/api.ts +69 -0
  111. package/packages/driver-smartcast/src/index.ts +1 -0
  112. package/packages/driver-smartcast/src/keymap.ts +9 -0
  113. package/packages/driver-smartcast/src/types.ts +102 -0
  114. package/packages/driver-tizen/src/DeviceTizen.ts +121 -7
  115. package/packages/driver-tizen/src/ITizen.ts +15116 -202
  116. package/packages/driver-tizen/src/IWebapis.ts +8643 -87
  117. package/packages/driver-tizen/src/TizenKeys.ts +4 -2
  118. package/packages/driver-tizen/src/__mocks__/tizen.ts +7 -8
  119. package/packages/driver-tizen/src/constants.ts +1 -195
  120. package/packages/driver-vidaa/src/DeviceVidaa.ts +29 -2
  121. package/packages/driver-vidaa/src/__mocks__/vidaa.ts +1 -1
  122. package/packages/driver-vidaa/src/keymap.ts +2 -0
  123. package/packages/driver-webos/src/DeviceWebos.ts +55 -0
  124. package/packages/driver-webos/src/__mocks__/webos.ts +33 -0
  125. package/packages/driver-webos/src/constants.ts +1 -0
  126. package/packages/driver-webos/src/keymap.ts +2 -1
  127. package/packages/driver-webos/src/types.ts +30 -0
  128. package/packages/driver-xbox/src/DeviceXbox.ts +30 -1
  129. package/packages/driver-xbox/src/keymap.ts +1 -1
  130. package/packages/epg/README.md +3 -1
  131. package/packages/epg/src/v2/Cell.tsx +16 -2
  132. package/packages/epg/src/v2/DataManager.ts +112 -41
  133. package/packages/epg/src/v2/DatePicker.tsx +9 -3
  134. package/packages/epg/src/v2/DateToast/DateToast.tsx +12 -9
  135. package/packages/epg/src/v2/Day.tsx +6 -3
  136. package/packages/epg/src/v2/Epg.tsx +5 -5
  137. package/packages/epg/src/v2/MockGenerator/generator.ts +3 -2
  138. package/packages/epg/src/v2/ProgramInfo/utils.ts +4 -3
  139. package/packages/epg/src/v2/Row.tsx +3 -1
  140. package/packages/epg/src/v2/TimelineSection.tsx +4 -1
  141. package/packages/epg/src/v2/basic/CellsManager.tsx +7 -2
  142. package/packages/epg/src/v2/basic/RowsManager.tsx +3 -1
  143. package/packages/epg/src/v2/interface.ts +13 -0
  144. package/packages/events-manager/src/EventsManager.ts +1 -56
  145. package/packages/focus/README.md +33 -0
  146. package/packages/focus/src/IFocusable.ts +1 -0
  147. package/packages/focus/src/Layout/Base.tsx +41 -6
  148. package/packages/focus/src/Layout/Matrix.tsx +51 -19
  149. package/packages/focus/src/focusFirstExisting.ts +7 -1
  150. package/packages/focus/src/hasFocus.ts +36 -0
  151. package/packages/focus/src/index.ts +2 -1
  152. package/packages/gallup/src/Gallup.ts +3 -3
  153. package/packages/grid/src/Base/Base.tsx +15 -10
  154. package/packages/grid/src/FirstOnlyGrid/FirstOnlyGrid.tsx +4 -2
  155. package/packages/grid/src/UnifiedGridController/UnifiedGridController.ts +6 -6
  156. package/packages/icon/src/Icon.tsx +27 -5
  157. package/packages/input/README.md +1 -1
  158. package/packages/input/src/Input.tsx +10 -10
  159. package/packages/interactable/README.md +2 -1
  160. package/packages/interactable/src/Interactable.tsx +9 -3
  161. package/packages/interactable/src/interface.ts +1 -0
  162. package/packages/jsx/src/index.ts +1 -1
  163. package/packages/jsx/src/test-utils/index.ts +1 -0
  164. package/packages/jsx/src/test-utils/keyup.ts +27 -0
  165. package/packages/keyboard/README.md +2 -0
  166. package/packages/keyboard/src/Backdrop/Backdrop.scss +2 -0
  167. package/packages/keyboard/src/KeyboardBase.tsx +16 -4
  168. package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.scss +10 -0
  169. package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.tsx +128 -142
  170. package/packages/keyboard/src/WhitelabelKeyboard/WhitelabelStyles/whitelabel.scss +4 -0
  171. package/packages/keyboard/src/WhitelabelKeyboard/_sizes.1080.scss +1 -0
  172. package/packages/keyboard/src/WhitelabelKeyboard/_sizes.scss +1 -0
  173. package/packages/keyboard/src/WhitelabelKeyboard/icons/key_language.svg +20 -0
  174. package/packages/keyboard/src/WhitelabelKeyboard/index.ts +1 -1
  175. package/packages/keyboard/src/WhitelabelKeyboard/layouts/arabic.ts +27 -0
  176. package/packages/keyboard/src/WhitelabelKeyboard/layouts/burmese.ts +27 -0
  177. package/packages/keyboard/src/WhitelabelKeyboard/layouts/dari.ts +28 -0
  178. package/packages/keyboard/src/WhitelabelKeyboard/layouts/hebrew.ts +28 -0
  179. package/packages/keyboard/src/WhitelabelKeyboard/layouts/index.ts +15 -0
  180. package/packages/keyboard/src/WhitelabelKeyboard/layouts/korean.ts +26 -0
  181. package/packages/keyboard/src/WhitelabelKeyboard/layouts/latin.ts +26 -0
  182. package/packages/keyboard/src/WhitelabelKeyboard/layouts/pashto.ts +27 -0
  183. package/packages/keyboard/src/WhitelabelKeyboard/layouts/persian.ts +27 -0
  184. package/packages/keyboard/src/WhitelabelKeyboard/layouts/russian.ts +27 -0
  185. package/packages/keyboard/src/WhitelabelKeyboard/layouts/spanish.ts +26 -0
  186. package/packages/keyboard/src/WhitelabelKeyboard/layouts/special.ts +28 -0
  187. package/packages/keyboard/src/WhitelabelKeyboard/layouts/tibetan.ts +26 -0
  188. package/packages/keyboard/src/WhitelabelKeyboard/layouts/turkish.ts +26 -0
  189. package/packages/keyboard/src/WhitelabelKeyboard/layouts/ukrainian.ts +27 -0
  190. package/packages/keyboard/src/WhitelabelKeyboard/layouts/urdu.ts +26 -0
  191. package/packages/keyboard/src/WhitelabelKeyboard/types.ts +22 -2
  192. package/packages/keyboard/src/types/index.ts +1 -1
  193. package/packages/keyboard/src/utils/caret.ts +5 -8
  194. package/packages/keyboard/src/utils/input.ts +5 -6
  195. package/packages/keyboard/src/utils/setInputSelectionRange.ts +10 -0
  196. package/packages/l10n/README.md +18 -0
  197. package/packages/l10n/src/date/common.ts +18 -6
  198. package/packages/l10n/src/date/cs.ts +2 -8
  199. package/packages/l10n/src/date/de.ts +97 -0
  200. package/packages/l10n/src/date/en-001.ts +3 -3
  201. package/packages/l10n/src/date/en-common.ts +5 -4
  202. package/packages/l10n/src/date/en-us.ts +3 -3
  203. package/packages/l10n/src/date/es.ts +71 -0
  204. package/packages/l10n/src/date/fr.ts +94 -0
  205. package/packages/l10n/src/date/he.ts +101 -0
  206. package/packages/l10n/src/date/iso.ts +12 -13
  207. package/packages/l10n/src/date/types.ts +9 -0
  208. package/packages/l10n/src/l10n.ts +61 -3
  209. package/packages/list/src/Base/Base.tsx +19 -9
  210. package/packages/list/src/Base/interface.ts +2 -2
  211. package/packages/list/src/BasicList/BasicList.tsx +7 -7
  212. package/packages/list/src/CenteredList/CenteredList.tsx +2 -2
  213. package/packages/list/src/CenteredList/controller.ts +0 -1
  214. package/packages/list/src/EdgeOffsetList/EdgeOffsetList.tsx +10 -10
  215. package/packages/list/src/FirstOnlyList/FirstOnlyList.tsx +2 -2
  216. package/packages/list/src/FirstOnlyVariedList/FirstOnlyVariedList.tsx +2 -2
  217. package/packages/list/src/FixedToEndList/FixedToEndList.tsx +2 -2
  218. package/packages/list/src/UnifiedListController/UnifiedListController.ts +6 -2
  219. package/packages/list/src/interface.ts +2 -2
  220. package/packages/logger/src/loggers/ConsoleLogger/ConsoleLogger.ts +7 -1
  221. package/packages/logger/src/loggers/SentryLogger/Sentry.ts +1 -0
  222. package/packages/logger/src/loggers/SentryLogger/SentryLogger.ts +5 -3
  223. package/packages/menu/src/MenuAndContentContainer/MenuAndContentContainer.tsx +31 -3
  224. package/packages/menu/src/MenuAndContentContainer/interface.ts +8 -0
  225. package/packages/modal-service/README.md +4 -1
  226. package/packages/modal-service/src/ModalService.tsx +29 -5
  227. package/packages/perf-utils/README.md +1 -120
  228. package/packages/perf-utils/src/array/filter.ts +1 -54
  229. package/packages/perf-utils/src/array/find.ts +1 -43
  230. package/packages/perf-utils/src/array/findIndex.ts +1 -43
  231. package/packages/perf-utils/src/array/forEach.ts +1 -48
  232. package/packages/perf-utils/src/array/includes.ts +1 -41
  233. package/packages/perf-utils/src/array/includesNaN.ts +1 -32
  234. package/packages/perf-utils/src/array/index.ts +1 -7
  235. package/packages/perf-utils/src/array/map.ts +1 -52
  236. package/packages/player-ui/README.md +1 -1
  237. package/packages/player-ui/src/CurrentTime.tsx +2 -2
  238. package/packages/player-ui/src/Duration.tsx +2 -2
  239. package/packages/player-ui/src/PauseButton.tsx +8 -0
  240. package/packages/player-ui/src/PlayerInteractable.tsx +1 -0
  241. package/packages/player-ui/src/PlayerTime.tsx +3 -1
  242. package/packages/player-ui/src/PlayerUI.tsx +68 -35
  243. package/packages/player-ui/src/RemainingTime.tsx +2 -2
  244. package/packages/player-ui/src/Seekbar.tsx +110 -18
  245. package/packages/player-ui/src/Seeking.ts +57 -16
  246. package/packages/player-ui/src/Subtitles.tsx +2 -2
  247. package/packages/player-ui/src/index.ts +1 -0
  248. package/packages/player-ui/src/mocks.ts +32 -8
  249. package/packages/player-ui/src/timeUtils.ts +3 -3
  250. package/packages/player-ui/src/types.ts +9 -3
  251. package/packages/router/README.md +1 -0
  252. package/packages/router/src/Route.tsx +61 -27
  253. package/packages/router/src/Router.tsx +63 -14
  254. package/packages/router/src/history.ts +8 -1
  255. package/packages/router/src/index.ts +1 -1
  256. package/packages/router/src/utils.ts +9 -4
  257. package/packages/sass-utils/src/linear-gradient.scss +9 -4
  258. package/packages/sass-utils/src/scale.1080.scss +3 -1
  259. package/packages/sass-utils/src/scale.720.scss +1 -1
  260. package/packages/time/README.md +4 -1
  261. package/packages/time/src/Time.ts +35 -13
  262. package/packages/time/src/adapters/24iMediaTimeApi.ts +47 -0
  263. package/packages/time/src/constants.ts +1 -0
  264. package/packages/time/src/services/24iMediaTimeApi/24iMediaTimeApi.ts +43 -0
  265. package/packages/time/src/services/24iMediaTimeApi/index.ts +6 -0
  266. package/packages/toast/src/ToastService.scss +1 -0
  267. package/packages/toast/src/ToastService.tsx +16 -5
  268. package/packages/types-bigscreen-jsx/README.md +5 -4
  269. package/packages/types-bigscreen-jsx/index.d.ts +72 -67
  270. package/packages/utils/README.md +27 -0
  271. package/packages/utils/src/elementUtils.ts +25 -0
  272. package/packages/utils/src/forceReflow.ts +14 -0
  273. package/packages/utils/src/index.ts +8 -0
  274. package/packages/utils/src/keyPress/index.ts +6 -0
  275. package/packages/utils/src/keyPress/keyPressSimulator.ts +74 -0
  276. package/packages/utils/src/keyPress/simulateKeyPress.ts +25 -0
  277. package/packages/utils/src/scaledImage.ts +6 -3
  278. package/packages/utils/src/textUtils.ts +46 -14
  279. package/packages/utils/src/wait.ts +3 -1
  280. package/packages/utils/src/xhr/xhrSend.ts +3 -1
  281. package/packages/utils/src/xhr/xhrSendRetry.ts +3 -1
  282. package/packages/zapping/src/ChannelZapping.ts +9 -0
  283. package/packages/zapping/src/Zapping.tsx +10 -0
  284. package/utils/release/release.ts +156 -0
  285. package/packages/driver-tizen/src/types.ts +0 -14
  286. package/packages/focus/src/Layout/__test__/Base.spec.ts +0 -180
  287. package/packages/focus/src/Layout/__test__/Horizontal.spec.ts +0 -94
  288. package/packages/focus/src/Layout/__test__/Matrix.spec.ts +0 -261
  289. package/packages/focus/src/Layout/__test__/Vertical.spec.ts +0 -46
  290. package/packages/focus/src/Layout/__test__/isRtl.spec.ts +0 -23
  291. package/packages/focus/src/Layout/__test__/shared.ts +0 -19
  292. 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,2 @@
1
+ export { DeviceAndroidTV } from './DeviceAndroidTV';
2
+ export type { IAPErrorEvent, IAPSuccessEvent } from './types';
@@ -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
  }