senza-sdk 4.2.64-70c0747.0 → 4.2.65-90c49ac.0
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/dist/bundle.js +1 -1
- package/package.json +7 -15
- package/src/{implementation/alarmManager.js → alarmManager.js} +52 -15
- package/src/api.js +350 -183
- package/src/{implementation/deviceManager.js → deviceManager.js} +65 -4
- package/src/{implementation/lifecycle.js → lifecycle.js} +215 -28
- package/src/{implementation/messageManager.js → messageManager.js} +6 -6
- package/src/{implementation/platformManager.js → platformManager.js} +4 -5
- package/src/{implementation/remotePlayer.js → remotePlayer.js} +22 -18
- package/src/{implementation/senzaShakaPlayer.js → senzaShakaPlayer.js} +28 -18
- package/src/{implementation/utils.js → utils.js} +6 -15
- package/src/implementation/api.js +0 -367
- package/src/interface/alarmManager.js +0 -69
- package/src/interface/api.js +0 -8
- package/src/interface/deviceManager.js +0 -133
- package/src/interface/lifecycle.js +0 -278
- package/src/interface/messageManager.js +0 -46
- package/src/interface/platformManager.js +0 -35
- package/src/interface/remotePlayer.js +0 -441
- package/src/interface/senzaShakaPlayer.js +0 -171
- package/src/interface/utils.js +0 -45
- /package/src/{implementation/SessionInfo.js → SessionInfo.js} +0 -0
- /package/src/{implementation/devHelper.js → devHelper.js} +0 -0
- /package/src/{interface/devSequence.js → devSequence.js} +0 -0
- /package/src/{implementation/eventListenersManager.js → eventListenersManager.js} +0 -0
- /package/src/{implementation/subtitlesUtils.js → subtitlesUtils.js} +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { DeviceManager as DeviceManagerInterface } from "../interface/deviceManager";
|
|
2
1
|
import { getFCID, sdkLogger, getRestResponse } from "./utils";
|
|
3
2
|
import { isRunningE2E } from "./api";
|
|
4
3
|
import { sessionInfo } from "./SessionInfo";
|
|
@@ -36,7 +35,10 @@ async function getWifiStatus() {
|
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
/**
|
|
39
|
+
* DeviceManager is a singleton class that manages the device
|
|
40
|
+
*/
|
|
41
|
+
class DeviceManager extends EventTarget {
|
|
40
42
|
|
|
41
43
|
constructor() {
|
|
42
44
|
super();
|
|
@@ -44,7 +46,15 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
44
46
|
wifiInfo.quality = 0;
|
|
45
47
|
wifiInfo.ssid = "unknown";
|
|
46
48
|
wifiInfo.bssid = "unknown";
|
|
47
|
-
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated Instead, call deviceManager.getWifiInfo() periodically
|
|
51
|
+
* @event DeviceManager#wifiInfoUpdated
|
|
52
|
+
* @example
|
|
53
|
+
* deviceManager.addEventListener("wifiInfoUpdated", () => {
|
|
54
|
+
* console.info("Wifi info has been updated to", deviceManager.wifiInfo);
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
48
58
|
typeof document !== "undefined" && document.addEventListener("wifiSignalReport", (e) => {
|
|
49
59
|
wifiInfo.level = e.detail.level;
|
|
50
60
|
wifiInfo.quality = e.detail.quality;
|
|
@@ -55,6 +65,17 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
55
65
|
|
|
56
66
|
}
|
|
57
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @property {object} DeviceInfo
|
|
70
|
+
* @property {string} DeviceInfo.deviceId
|
|
71
|
+
* @property {string} DeviceInfo.modelNumber
|
|
72
|
+
* @property {string} DeviceInfo.connectionId
|
|
73
|
+
* @property {string} DeviceInfo.community
|
|
74
|
+
* @property {string} DeviceInfo.tenant
|
|
75
|
+
* @property {string} DeviceInfo.clientIp
|
|
76
|
+
* @property {string} DeviceInfo.countryCode A 2-letter code as defined in ISO_3166-1
|
|
77
|
+
* @property {string} DeviceInfo.connectionType The type of device used during the current connection. Possible values are "device" which mean real device, "simulator" - simulated device - that used during development.
|
|
78
|
+
*/
|
|
58
79
|
get deviceInfo() {
|
|
59
80
|
const sessionInfoObj = sessionInfo.sessionInfoObj;
|
|
60
81
|
if (isRunningE2E() && sessionInfoObj) {
|
|
@@ -82,10 +103,23 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
82
103
|
};
|
|
83
104
|
}
|
|
84
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @deprecated use deviceManager.getWifiInfo() instead
|
|
108
|
+
* @property {object} WifiInfo
|
|
109
|
+
* @property {number} WifiInfo.level
|
|
110
|
+
* @property {number} WifiInfo.quality
|
|
111
|
+
* @property {string} WifiInfo.ssid
|
|
112
|
+
* @property {string} WifiInfo.bssid
|
|
113
|
+
*/
|
|
85
114
|
get wifiInfo() {
|
|
86
115
|
return wifiInfo;
|
|
87
116
|
}
|
|
88
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Reboot the device
|
|
120
|
+
* @return {Promise} Promise which is resolved when the reboot command has been successfully processed.
|
|
121
|
+
* Failure to process the reboot command will result in the promise being rejected.
|
|
122
|
+
*/
|
|
89
123
|
reboot() {
|
|
90
124
|
return new Promise((resolve, reject) => {
|
|
91
125
|
if (window.cefQuery) {
|
|
@@ -115,6 +149,11 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
115
149
|
});
|
|
116
150
|
}
|
|
117
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Delete current wifi configuration and forget network
|
|
154
|
+
* @return {Promise} Promise which is resolved when the clearWifi command has been successfully processed.
|
|
155
|
+
* Failure to process the clearWifi command will result in the promise being rejected.
|
|
156
|
+
*/
|
|
118
157
|
clearWifi() {
|
|
119
158
|
return new Promise((resolve, reject) => {
|
|
120
159
|
const FCID = getFCID();
|
|
@@ -139,6 +178,16 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
139
178
|
});
|
|
140
179
|
}
|
|
141
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Send raw data directly to a customer's device via the USB serial connection of a Senza device.
|
|
183
|
+
* This function is specifically designed for customers who have their devices connected to a Senza device.
|
|
184
|
+
* Using this API, these customers can transmit messages or data directly to their connected devices.
|
|
185
|
+
* The transmission occurs through the Senza device's USB serial interface, facilitating direct communication
|
|
186
|
+
* between the customer's web application and their device.
|
|
187
|
+
* @param {String} data raw data to be passed to the device
|
|
188
|
+
* @return {Promise} Promise which is resolved when the command has been successfully processed.
|
|
189
|
+
* Failure to process the command will result in the promise being rejected.
|
|
190
|
+
*/
|
|
142
191
|
sendDataToDevice(data) {
|
|
143
192
|
if (typeof data !== "string") {
|
|
144
193
|
throw new Error("data must be of type 'string'");
|
|
@@ -170,6 +219,12 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
170
219
|
});
|
|
171
220
|
}
|
|
172
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Perform device factory reset.
|
|
224
|
+
* @param {Boolean} [reboot=true] a flag that is passed to the device to indicate whether it should reboot after the factory reset. defaults to true.
|
|
225
|
+
* @return {Promise} Promise which is resolved when factoryReset has been successfully performed
|
|
226
|
+
* Failure to factoryReset for any reason, result in the promise being rejected.
|
|
227
|
+
*/
|
|
173
228
|
async factoryReset(reboot = true) {
|
|
174
229
|
if (typeof reboot !== "boolean") {
|
|
175
230
|
throw new Error("reboot param must be of type 'boolean'");
|
|
@@ -227,6 +282,12 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
227
282
|
* @property {number} quality a measure of the signal quality, in the range 0 to 100 (the higher, the better). The quality value is derived from the signal EVM.
|
|
228
283
|
* */
|
|
229
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Get Wi-Fi info - access point data and status (the status is cached for 5 seconds)
|
|
287
|
+
* @returns {WiFiInfo} An object containing the Wi-Fi info
|
|
288
|
+
* @alpha API has not yet been released
|
|
289
|
+
* */
|
|
290
|
+
// This api is part of epic HSDEV-4185
|
|
230
291
|
async getWifiInfo() {
|
|
231
292
|
await Promise.all([getWifiApData(), getWifiStatus()]);
|
|
232
293
|
return { ...wifi_ap_data, ...wifi_status };
|
|
@@ -234,7 +295,7 @@ class DeviceManager extends DeviceManagerInterface {
|
|
|
234
295
|
}
|
|
235
296
|
|
|
236
297
|
/**
|
|
237
|
-
|
|
298
|
+
*
|
|
238
299
|
* @module
|
|
239
300
|
* @example
|
|
240
301
|
* import { deviceManager } from "senza-sdk";
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getPlatformInfo } from "./api";
|
|
3
|
-
import { alarmManager } from "./alarmManager";
|
|
1
|
+
import { alarmManager, getPlatformInfo } from "./api";
|
|
4
2
|
import {
|
|
5
3
|
getFCID,
|
|
6
4
|
isAudioSyncConfigured,
|
|
@@ -26,7 +24,76 @@ const DEFAULT_AUTO_BACKGROUND_ENABLED = false;
|
|
|
26
24
|
* @fires userinactivity
|
|
27
25
|
* @fires userdisconnected
|
|
28
26
|
*/
|
|
29
|
-
class Lifecycle extends
|
|
27
|
+
class Lifecycle extends EventTarget {
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} ConnectReason - The reason the ui app has been loaded
|
|
31
|
+
* @property {string} UNKNOWN
|
|
32
|
+
* @property {string} INITIAL_CONNECTION - Indicates that ui app has been loaded for the first time
|
|
33
|
+
* @property {string} APPLICATION_RELOAD - Indicates that ui app has been reloaded (e.g. after HOME keypress)
|
|
34
|
+
* @property {string} UI_RELEASE - Indicates that ui app has been reloaded after ui release
|
|
35
|
+
* @property {string} UI_TERMINATION - Indicates that ui app has been reloaded due to ui termination
|
|
36
|
+
* @property {string} WEBRTC_ERROR - Indicates that ui app has been reloaded due to webrtc error
|
|
37
|
+
* @property {string} UI_WATCHDOG - Indicates that ui app has been reloaded due to ui watchdog not receiving ui frames
|
|
38
|
+
*/
|
|
39
|
+
ConnectReason = Object.freeze({
|
|
40
|
+
UNKNOWN: "unknown",
|
|
41
|
+
INITIAL_CONNECTION: "initial_connection",
|
|
42
|
+
APPLICATION_RELOAD: "reload_app",
|
|
43
|
+
UI_RELEASE: "ui_release",
|
|
44
|
+
UI_TERMINATION: "ui_termination",
|
|
45
|
+
WEBRTC_ERROR: "webrtc_error",
|
|
46
|
+
UI_WATCHDOG: "ui_watchdog"
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {Object} UiState - The ui lifecycle state
|
|
51
|
+
* @property {string} UNKNOWN - state is unknown at this time
|
|
52
|
+
* @property {string} FOREGROUND - ui is displayed
|
|
53
|
+
* @property {string} IN_TRANSITION_TO_FOREGROUND - ui is about to be displayed
|
|
54
|
+
* @property {string} BACKGROUND - remote player is playing (full screen playback is displayed)
|
|
55
|
+
* @property {string} IN_TRANSITION_TO_BACKGROUND - remote player is about to be playing
|
|
56
|
+
*/
|
|
57
|
+
UiState = Object.freeze({
|
|
58
|
+
UNKNOWN: "unknown",
|
|
59
|
+
FOREGROUND: "foreground",
|
|
60
|
+
IN_TRANSITION_TO_FOREGROUND: "inTransitionToForeground",
|
|
61
|
+
BACKGROUND: "background",
|
|
62
|
+
IN_TRANSITION_TO_BACKGROUND: "inTransitionToBackground"
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @event Lifecycle#onstatechange
|
|
67
|
+
* @description Fired after transition from one state to another.<br>
|
|
68
|
+
* The flow is: foreground --> inTransitionToBackground --> background --> inTransitionToForeground --> foreground
|
|
69
|
+
* @property {UiState} state - Indicates the new state.
|
|
70
|
+
* @example
|
|
71
|
+
* lifecycle.addEventListener("onstatechange", (e) => {
|
|
72
|
+
* console.log("new state is", e.state);
|
|
73
|
+
* });
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @event Lifecycle#userinactivity
|
|
78
|
+
* @description Fired after the ui has been inactive (i.e. no key presses) for a configurable number of seconds.<br>
|
|
79
|
+
* @property {number} timeout - the number of seconds after which the application will be unloaded.
|
|
80
|
+
* @example
|
|
81
|
+
* lifecycle.addEventListener("userinactivity", (e) => {
|
|
82
|
+
* console.log(`Application will be unloaded in ${e.timeout} seconds`);
|
|
83
|
+
* });
|
|
84
|
+
* @alpha API has not yet been released
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @event Lifecycle#userdisconnected
|
|
89
|
+
* @description Fired when the user session ends .
|
|
90
|
+
* This event is useful for cleaning up application state or saving data before the application closes. Event callback should return promise to ensure that the event is handled before the application is terminated
|
|
91
|
+
* @example
|
|
92
|
+
* lifecycle.addEventListener("userdisconnected", () => {
|
|
93
|
+
* console.log("User session ended, cleaning up application state");
|
|
94
|
+
* // Perform any necessary cleanup here
|
|
95
|
+
* });
|
|
96
|
+
*/
|
|
30
97
|
constructor() {
|
|
31
98
|
super();
|
|
32
99
|
|
|
@@ -35,7 +102,9 @@ class Lifecycle extends LifecycleInterface {
|
|
|
35
102
|
* @private
|
|
36
103
|
*/
|
|
37
104
|
this._isInitialized = false;
|
|
38
|
-
this.
|
|
105
|
+
this._inTransitionToForeground = false;
|
|
106
|
+
this._inTransitionToBackground = false;
|
|
107
|
+
this._inTransitionToStandby = false;
|
|
39
108
|
|
|
40
109
|
/**
|
|
41
110
|
* Event listeners manager for the userdisconnected event
|
|
@@ -238,6 +307,15 @@ class Lifecycle extends LifecycleInterface {
|
|
|
238
307
|
return this._autoBackgroundOnUIDelay;
|
|
239
308
|
}
|
|
240
309
|
|
|
310
|
+
/**
|
|
311
|
+
* Configure lifecycle settings
|
|
312
|
+
* @param {Object} config - Configuration object
|
|
313
|
+
* @param {Object} [config.autoBackground] - Auto background settings
|
|
314
|
+
* @param {boolean} [config.autoBackground.enabled] - Enable/disable auto background
|
|
315
|
+
* @param {Object} [config.autoBackground.timeout] - Timeout settings
|
|
316
|
+
* @param {number|false} [config.autoBackground.timeout.playing=30] - Timeout in seconds when video is playing, false to disable
|
|
317
|
+
* @param {number|false} [config.autoBackground.timeout.idle=false] - Timeout in seconds when in UI mode, false to disable
|
|
318
|
+
*/
|
|
241
319
|
configure(config) {
|
|
242
320
|
if (config?.autoBackground) {
|
|
243
321
|
const { enabled, timeout } = config.autoBackground;
|
|
@@ -277,6 +355,15 @@ class Lifecycle extends LifecycleInterface {
|
|
|
277
355
|
}
|
|
278
356
|
}
|
|
279
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Get the current configuration settings
|
|
360
|
+
* @returns {Object} The current configuration object
|
|
361
|
+
* @example
|
|
362
|
+
* const config = lifecycle.getConfiguration();
|
|
363
|
+
* console.log(config.autoBackground.enabled); // true/false
|
|
364
|
+
* console.log(config.autoBackground.timeout.playing); // 30
|
|
365
|
+
* console.log(config.autoBackground.timeout.idle); // false
|
|
366
|
+
*/
|
|
280
367
|
getConfiguration() {
|
|
281
368
|
return {
|
|
282
369
|
autoBackground: {
|
|
@@ -299,7 +386,7 @@ class Lifecycle extends LifecycleInterface {
|
|
|
299
386
|
// This api is part of epic HSDEV-713
|
|
300
387
|
_moveToUiStandby() {
|
|
301
388
|
if (window.cefQuery) {
|
|
302
|
-
this.
|
|
389
|
+
this._inTransitionToStandby = true;
|
|
303
390
|
return new Promise((resolve, reject) => {
|
|
304
391
|
const FCID = getFCID();
|
|
305
392
|
const request = { target: "TC", waitForResponse: false, internalAction: "uiExit", message: JSON.stringify({ type: "uiStandbyRequest", fcid: FCID }) };
|
|
@@ -310,12 +397,12 @@ class Lifecycle extends LifecycleInterface {
|
|
|
310
397
|
persistent: false,
|
|
311
398
|
onSuccess: () => {
|
|
312
399
|
logger.log("[ moveToUiStandby ] moveToUiStandby successfully sent");
|
|
313
|
-
this.
|
|
400
|
+
this._inTransitionToStandby = false;
|
|
314
401
|
resolve(true);
|
|
315
402
|
},
|
|
316
403
|
onFailure: (code, msg) => {
|
|
317
404
|
logger.error(`[ moveToUiStandby ] moveToUiStandby failed: ${code} ${msg}`);
|
|
318
|
-
this.
|
|
405
|
+
this._inTransitionToStandby = false;
|
|
319
406
|
reject(`moveToUiStandby failed: ${code} ${msg}`);
|
|
320
407
|
}
|
|
321
408
|
});
|
|
@@ -325,6 +412,10 @@ class Lifecycle extends LifecycleInterface {
|
|
|
325
412
|
return Promise.resolve(true);
|
|
326
413
|
}
|
|
327
414
|
|
|
415
|
+
/**
|
|
416
|
+
* Getter for returning the ui lifecycle state
|
|
417
|
+
* @returns {UiState} the current application lifecycle state
|
|
418
|
+
*/
|
|
328
419
|
get state() {
|
|
329
420
|
if (!this._isInitialized) {
|
|
330
421
|
this._state = this.UiState.UNKNOWN;
|
|
@@ -332,6 +423,10 @@ class Lifecycle extends LifecycleInterface {
|
|
|
332
423
|
return this._state;
|
|
333
424
|
}
|
|
334
425
|
|
|
426
|
+
/**
|
|
427
|
+
* Getter for returning the application connection reason
|
|
428
|
+
* @returns {ConnectReason} the application connection reason
|
|
429
|
+
*/
|
|
335
430
|
get connectReason() {
|
|
336
431
|
if (!this._isInitialized) {
|
|
337
432
|
this._connectReason = this.ConnectReason.UNKNOWN;
|
|
@@ -339,6 +434,11 @@ class Lifecycle extends LifecycleInterface {
|
|
|
339
434
|
return this._connectReason;
|
|
340
435
|
}
|
|
341
436
|
|
|
437
|
+
/**
|
|
438
|
+
* Getter for returning the event that triggered the reloading of the ui after ui has been released
|
|
439
|
+
* @returns {Object} trigger event
|
|
440
|
+
* @property {string} type - the type of the trigger event (e.g. keyPressEvent, videoPlaybackEvent)
|
|
441
|
+
* @property {object} data - data of the event, dependent on its type (e.g. keyPressEvent has data of keyValue) */
|
|
342
442
|
get triggerEvent() {
|
|
343
443
|
if (!this._isInitialized) {
|
|
344
444
|
this._triggerEvent = {};
|
|
@@ -346,6 +446,14 @@ class Lifecycle extends LifecycleInterface {
|
|
|
346
446
|
return this._triggerEvent;
|
|
347
447
|
}
|
|
348
448
|
|
|
449
|
+
/**
|
|
450
|
+
* @deprecated Use `lifecycle.configure()` instead.
|
|
451
|
+
* Controls the autoBackground feature.<br>
|
|
452
|
+
* When enabled, the application will automatically move to the background state after a configurable
|
|
453
|
+
* period of inactivity. Use the `configure` method to set timeouts for video playback and UI states.
|
|
454
|
+
* @type {boolean}
|
|
455
|
+
* @see {@link Lifecycle#configure}
|
|
456
|
+
*/
|
|
349
457
|
set autoBackground(enabled) {
|
|
350
458
|
this._autoBackground = enabled;
|
|
351
459
|
if (this._isAutoBackgroundEnabled()) {
|
|
@@ -359,6 +467,14 @@ class Lifecycle extends LifecycleInterface {
|
|
|
359
467
|
return this._autoBackground;
|
|
360
468
|
}
|
|
361
469
|
|
|
470
|
+
/**
|
|
471
|
+
* @deprecated Use `lifecycle.configure()` instead.
|
|
472
|
+
* The number of seconds of user inactivity before the application moves to the background state while playing video.
|
|
473
|
+
* Use the `configure` method to set this timeout.
|
|
474
|
+
* @type {integer}
|
|
475
|
+
* @default 30
|
|
476
|
+
* @see {@link Lifecycle#configure}
|
|
477
|
+
*/
|
|
362
478
|
set autoBackgroundDelay(delay) {
|
|
363
479
|
this._autoBackgroundOnVideoDelay = delay;
|
|
364
480
|
if (this._isAutoBackgroundEnabled() && remotePlayer._isPlaying) {
|
|
@@ -370,6 +486,14 @@ class Lifecycle extends LifecycleInterface {
|
|
|
370
486
|
return this._autoBackgroundOnVideoDelay;
|
|
371
487
|
}
|
|
372
488
|
|
|
489
|
+
/**
|
|
490
|
+
* @deprecated Use `lifecycle.configure()` instead.
|
|
491
|
+
* The number of seconds of user inactivity before the application moves to the background state while in the UI (not playing).
|
|
492
|
+
* Use the `configure` method to set this timeout.
|
|
493
|
+
* @type {integer}
|
|
494
|
+
* @default -1
|
|
495
|
+
* @see {@link Lifecycle#configure}
|
|
496
|
+
*/
|
|
373
497
|
set autoBackgroundOnUIDelay(delay) {
|
|
374
498
|
this._autoBackgroundOnUIDelay = delay;
|
|
375
499
|
if (this._isAutoBackgroundEnabled() && !remotePlayer._isPlaying) {
|
|
@@ -412,6 +536,26 @@ class Lifecycle extends LifecycleInterface {
|
|
|
412
536
|
this._countdown = null;
|
|
413
537
|
}
|
|
414
538
|
|
|
539
|
+
/**
|
|
540
|
+
* @private
|
|
541
|
+
*/
|
|
542
|
+
_isInTransition() {
|
|
543
|
+
return this._inTransitionToForeground || this._inTransitionToBackground || this._inTransitionToStandby;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* @deprecated use lifecycle.state instead.
|
|
549
|
+
* Async function that returns the ui lifecycle state
|
|
550
|
+
* @returns {UiState} the current application lifecycle state
|
|
551
|
+
* @example
|
|
552
|
+
* try {
|
|
553
|
+
* const state = await lifecycle.getState();
|
|
554
|
+
* console.log("current state is", state);
|
|
555
|
+
* } catch (e) {
|
|
556
|
+
* console.error("getState failed", e);
|
|
557
|
+
* }
|
|
558
|
+
*/
|
|
415
559
|
getState() {
|
|
416
560
|
if (window.cefQuery) {
|
|
417
561
|
return new Promise((resolve, reject) => {
|
|
@@ -432,16 +576,29 @@ class Lifecycle extends LifecycleInterface {
|
|
|
432
576
|
sdkLogger.warn("lifecycle getState is not supported if NOT running e2e");
|
|
433
577
|
}
|
|
434
578
|
|
|
579
|
+
/**
|
|
580
|
+
* Once playback starts on the remote player,
|
|
581
|
+
* the application is moved from foreground to inTransitionToBackground and eventually to background.
|
|
582
|
+
* The application will need to call moveToForeground when it receives an event that needs the UI to be displayed again,
|
|
583
|
+
* for example a key press, a playback end-of-file or a playback error.
|
|
584
|
+
* @return {Promise} Promise which is resolved when the moveToForeground command has been successfully processed.
|
|
585
|
+
* Failure to process the moveToForeground command will result in the promise being rejected.
|
|
586
|
+
*/
|
|
435
587
|
moveToForeground() {
|
|
436
588
|
if (window.cefQuery) {
|
|
437
|
-
|
|
438
|
-
|
|
589
|
+
const inTransition = this._isInTransition();
|
|
590
|
+
if (inTransition || this._state === this.UiState.FOREGROUND || this._state === this.UiState.IN_TRANSITION_TO_FOREGROUND) {
|
|
591
|
+
sdkLogger.warn(`lifecycle moveToForeground: No need to transition to foreground, state: ${this._state} transition: ${inTransition}`);
|
|
439
592
|
return Promise.resolve(false);
|
|
440
593
|
}
|
|
441
|
-
this.
|
|
594
|
+
this._inTransitionToForeground = true;
|
|
442
595
|
alarmManager._moveToForegroundCalled();
|
|
443
596
|
const FCID = getFCID();
|
|
444
597
|
if (this._remotePlayerApiVersion >= 2) {
|
|
598
|
+
// Only update to playing UI if we started seeking in ABR. But, if we are seeking while already paused, keep the target seek state as is.
|
|
599
|
+
if (remotePlayer._isSeekingByApplication && remotePlayer._targetSeekPlayingState === TargetPlayingState.PLAYING_ABR) {
|
|
600
|
+
remotePlayer._targetSeekPlayingState = TargetPlayingState.PLAYING_UI;
|
|
601
|
+
}
|
|
445
602
|
return new Promise((resolve, reject) => {
|
|
446
603
|
const FCID = getFCID();
|
|
447
604
|
const logger = sdkLogger.withFields({ FCID });
|
|
@@ -461,14 +618,14 @@ class Lifecycle extends LifecycleInterface {
|
|
|
461
618
|
onSuccess: () => {
|
|
462
619
|
const duration = Date.now() - timeBeforeSendingRequest;
|
|
463
620
|
logger.withFields({ duration }).log(`stop completed successfully after ${duration} ms`);
|
|
464
|
-
this.
|
|
621
|
+
this._inTransitionToForeground = false;
|
|
465
622
|
timerId = clearTimer(timerId);
|
|
466
623
|
resolve(true);
|
|
467
624
|
},
|
|
468
625
|
onFailure: (code, msg) => {
|
|
469
626
|
const duration = Date.now() - timeBeforeSendingRequest;
|
|
470
627
|
logger.withFields({ duration }).log(`stop failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
|
|
471
|
-
this.
|
|
628
|
+
this._inTransitionToForeground = false;
|
|
472
629
|
timerId = clearTimer(timerId);
|
|
473
630
|
reject(new SenzaError(code, msg));
|
|
474
631
|
}
|
|
@@ -477,7 +634,7 @@ class Lifecycle extends LifecycleInterface {
|
|
|
477
634
|
const timeout = this._remotePlayerConfirmationTimeout + 1000;
|
|
478
635
|
timerId = setTimeout(() => {
|
|
479
636
|
logger.log(`stop reached timeout of ${timeout} ms, canceling query id ${queryId}`);
|
|
480
|
-
this.
|
|
637
|
+
this._inTransitionToForeground = false;
|
|
481
638
|
window.cefQueryCancel(queryId);
|
|
482
639
|
reject(new SenzaError(6000, `stop reached timeout of ${timeout} ms`));
|
|
483
640
|
}, timeout, queryId);
|
|
@@ -492,11 +649,11 @@ class Lifecycle extends LifecycleInterface {
|
|
|
492
649
|
persistent: false,
|
|
493
650
|
onSuccess: () => {
|
|
494
651
|
logger.log("uiActiveRequest successfully sent");
|
|
495
|
-
this.
|
|
652
|
+
this._inTransitionToForeground = false;
|
|
496
653
|
resolve(true);
|
|
497
654
|
},
|
|
498
655
|
onFailure: (code, msg) => {
|
|
499
|
-
this.
|
|
656
|
+
this._inTransitionToForeground = false;
|
|
500
657
|
logger.error(`uiActiveRequest failed: ${code} ${msg}`);
|
|
501
658
|
reject(`uiActiveRequest failed: ${code} ${msg}`);
|
|
502
659
|
}
|
|
@@ -509,10 +666,6 @@ class Lifecycle extends LifecycleInterface {
|
|
|
509
666
|
|
|
510
667
|
_moveToBackground() {
|
|
511
668
|
if (window.cefQuery) {
|
|
512
|
-
if (this._inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
|
|
513
|
-
sdkLogger.warn(`lifecycle moveToBackground: No need to transition to background, state: ${this._state} transition: ${this._inTransition}`);
|
|
514
|
-
return Promise.resolve(false);
|
|
515
|
-
}
|
|
516
669
|
// If audio sync is disabled, we only need to sync before remote player starts playing
|
|
517
670
|
if (!isAudioSyncConfigured()) {
|
|
518
671
|
remotePlayer._syncRemotePlayerWithLocalPlayer();
|
|
@@ -524,7 +677,7 @@ class Lifecycle extends LifecycleInterface {
|
|
|
524
677
|
return this._moveToUiStandby();
|
|
525
678
|
}
|
|
526
679
|
|
|
527
|
-
this.
|
|
680
|
+
this._inTransitionToBackground = true;
|
|
528
681
|
return new Promise((resolve, reject) => {
|
|
529
682
|
const FCID = getFCID();
|
|
530
683
|
const logger = sdkLogger.withFields({ FCID });
|
|
@@ -565,14 +718,14 @@ class Lifecycle extends LifecycleInterface {
|
|
|
565
718
|
onSuccess: () => {
|
|
566
719
|
const duration = Date.now() - timeBeforeSendingRequest;
|
|
567
720
|
logger.withFields({ duration }).log(`play completed successfully after ${duration} ms`);
|
|
568
|
-
this.
|
|
721
|
+
this._inTransitionToBackground = false;
|
|
569
722
|
timerId = clearTimer(timerId);
|
|
570
723
|
resolve();
|
|
571
724
|
},
|
|
572
725
|
onFailure: (code, msg) => {
|
|
573
726
|
const duration = Date.now() - timeBeforeSendingRequest;
|
|
574
727
|
logger.withFields({ duration }).log(`play failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
|
|
575
|
-
this.
|
|
728
|
+
this._inTransitionToBackground = false;
|
|
576
729
|
timerId = clearTimer(timerId);
|
|
577
730
|
reject(new SenzaError(code, msg));
|
|
578
731
|
}
|
|
@@ -582,7 +735,7 @@ class Lifecycle extends LifecycleInterface {
|
|
|
582
735
|
const timeout = this._remotePlayerConfirmationTimeout + 1000;
|
|
583
736
|
timerId = setTimeout(() => {
|
|
584
737
|
logger.log(`play reached timeout of ${timeout} ms, canceling query id ${queryId}`);
|
|
585
|
-
this.
|
|
738
|
+
this._inTransitionToBackground = false;
|
|
586
739
|
window.cefQueryCancel(queryId);
|
|
587
740
|
reject(new SenzaError(6000, `play reached timeout of ${timeout} ms`));
|
|
588
741
|
}, timeout, queryId);
|
|
@@ -593,13 +746,24 @@ class Lifecycle extends LifecycleInterface {
|
|
|
593
746
|
return Promise.resolve(false);
|
|
594
747
|
}
|
|
595
748
|
|
|
749
|
+
/**
|
|
750
|
+
* This method moves the application to the background.
|
|
751
|
+
* It should be called after remotePlayer.play().
|
|
752
|
+
* As a consequence, remote player playback will be displayed in full screen.
|
|
753
|
+
* @example
|
|
754
|
+
* remotePlayer.load("https://example.com/video.mp4", 0);
|
|
755
|
+
* remotePlayer.play();
|
|
756
|
+
* lifecycle.moveToBackground();
|
|
757
|
+
* @return {Promise} Promise which is resolved when the moveToBackground command has been successfully processed.
|
|
758
|
+
* Failure to process the moveToBackground command will result in the promise being rejected.
|
|
759
|
+
*/
|
|
596
760
|
moveToBackground() {
|
|
597
761
|
if (window.cefQuery) {
|
|
598
|
-
|
|
599
|
-
|
|
762
|
+
const inTransition = this._isInTransition();
|
|
763
|
+
if (inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
|
|
764
|
+
sdkLogger.warn(`lifecycle moveToBackground: No need to transition to background, state: ${this._state} transition: ${inTransition}`);
|
|
600
765
|
return Promise.resolve(false);
|
|
601
766
|
}
|
|
602
|
-
|
|
603
767
|
if (remotePlayer._isSeekingByApplication) {
|
|
604
768
|
remotePlayer._targetSeekPlayingState = TargetPlayingState.PLAYING_ABR;
|
|
605
769
|
return Promise.resolve(true);
|
|
@@ -616,6 +780,13 @@ class Lifecycle extends LifecycleInterface {
|
|
|
616
780
|
return this._moveToBackground();
|
|
617
781
|
}
|
|
618
782
|
|
|
783
|
+
/**
|
|
784
|
+
* Use this api to switch to another tenant (other than the home tenant) which will launch the application associated with the tenantId. The tenantId must be configured in the
|
|
785
|
+
* Senza platform. Switching to the home tenant should use the exitApplication().
|
|
786
|
+
* @param {string} tenantId The tenantId to switch
|
|
787
|
+
* @return {Promise} Promise which is resolved when the switchTenant command has been successfully processed.
|
|
788
|
+
* Failure to process the switchTenant command will result in the promise being rejected.
|
|
789
|
+
*/
|
|
619
790
|
switchTenant(tenantId) {
|
|
620
791
|
if (tenantId && tenantId.length > 0) {
|
|
621
792
|
if (tenantId === getPlatformInfo().sessionInfo?.tenantId) {
|
|
@@ -661,6 +832,11 @@ class Lifecycle extends LifecycleInterface {
|
|
|
661
832
|
return Promise.reject("SwitchTenant requires a valid tenantId string parameter");
|
|
662
833
|
}
|
|
663
834
|
|
|
835
|
+
/**
|
|
836
|
+
* Use this api to exit the application which will redirect the browser to the home tenant application.
|
|
837
|
+
* @return {Promise} Promise which is resolved when the exitApplication command has been successfully processed.
|
|
838
|
+
* Failure to process the exitApplication command will result in the promise being rejected.
|
|
839
|
+
*/
|
|
664
840
|
exitApplication() {
|
|
665
841
|
if (window.cefQuery) {
|
|
666
842
|
return new Promise((resolve, reject) => {
|
|
@@ -709,6 +885,12 @@ class Lifecycle extends LifecycleInterface {
|
|
|
709
885
|
return Promise.reject("exitApplication is not supported if NOT running e2e");
|
|
710
886
|
}
|
|
711
887
|
|
|
888
|
+
/**
|
|
889
|
+
* Add event listener for lifecycle events
|
|
890
|
+
* @param {string} type - The event type to listen for
|
|
891
|
+
* @param {Function} listener - The callback function. Listeners for 'userdisconnected' events should return a promise to ensure the event is processed before the application exits.
|
|
892
|
+
* @param {Object} options - Event listener options
|
|
893
|
+
*/
|
|
712
894
|
addEventListener(type, listener, options) {
|
|
713
895
|
if (type === "userdisconnected") {
|
|
714
896
|
// Use the event manager for userdisconnected events
|
|
@@ -719,7 +901,12 @@ class Lifecycle extends LifecycleInterface {
|
|
|
719
901
|
}
|
|
720
902
|
}
|
|
721
903
|
|
|
722
|
-
|
|
904
|
+
/**
|
|
905
|
+
* Remove event listener
|
|
906
|
+
* @param {string} type - The event type
|
|
907
|
+
* @param {Function} listener - The callback function to remove
|
|
908
|
+
* @param {Object} options - Event listener options
|
|
909
|
+
*/
|
|
723
910
|
removeEventListener(type, listener, options) {
|
|
724
911
|
if (type === "userdisconnected") {
|
|
725
912
|
// Use the event manager for userdisconnected events
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
|
|
2
|
+
import {getFCID, sdkLogger} from "./utils";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* MessageManager is a singleton class that manages the external messages received by the application. It fires custom events as "message" with the payload as the content
|
|
6
6
|
* @fires MessageManager#message
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
class MessageManager extends
|
|
9
|
+
class MessageManager extends EventTarget {
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {object} MessageDetails - object which contains the content of the message
|
|
@@ -34,7 +34,7 @@ class MessageManager extends MessageManagerInterface {
|
|
|
34
34
|
super();
|
|
35
35
|
typeof document !== "undefined" && document.addEventListener("hs/externalEvent", (e) => {
|
|
36
36
|
sdkLogger.log("Got hs/externalEvent", JSON.stringify(e.detail));
|
|
37
|
-
this.dispatchEvent(new CustomEvent("message", {
|
|
37
|
+
this.dispatchEvent(new CustomEvent("message", {detail: {eventName: e.detail.eventName, payload: e.detail.payload, fcid: e.detail.fcid } }));
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -49,13 +49,13 @@ class MessageManager extends MessageManagerInterface {
|
|
|
49
49
|
return new Promise((resolve, reject) => {
|
|
50
50
|
if (window.cefQuery) {
|
|
51
51
|
const FCID = getFCID();
|
|
52
|
-
const logger = sdkLogger.withFields({
|
|
52
|
+
const logger = sdkLogger.withFields({FCID});
|
|
53
53
|
const message = {
|
|
54
54
|
type: "registerGroupEvent",
|
|
55
55
|
fcid: FCID,
|
|
56
56
|
groups
|
|
57
57
|
};
|
|
58
|
-
const request = {
|
|
58
|
+
const request = {target: "UI-Streamer", waitForResponse: false, message: JSON.stringify(message)};
|
|
59
59
|
window.cefQuery({
|
|
60
60
|
request: JSON.stringify(request),
|
|
61
61
|
persistent: false,
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { PlatformManager as PlatformManagerInterface } from "../interface/platformManager";
|
|
2
1
|
import { sdkLogger } from "./utils";
|
|
3
|
-
import {
|
|
2
|
+
import {sessionInfo} from "./SessionInfo";
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* PlatformManager is a singleton class that manages the platform
|
|
8
7
|
*/
|
|
9
|
-
class PlatformManager extends
|
|
8
|
+
class PlatformManager extends EventTarget {
|
|
10
9
|
|
|
11
10
|
constructor() {
|
|
12
11
|
super();
|
|
@@ -23,7 +22,7 @@ class PlatformManager extends PlatformManagerInterface {
|
|
|
23
22
|
get appConfig() {
|
|
24
23
|
const sessionInfoObj = sessionInfo.sessionInfoObj;
|
|
25
24
|
const appConfig = sessionInfoObj.homeSessionInfo?.["appConfig"] || {};
|
|
26
|
-
sdkLogger.info("PlatformManager get appConfig: \n" + JSON.stringify(appConfig, null,
|
|
25
|
+
sdkLogger.info("PlatformManager get appConfig: \n" + JSON.stringify(appConfig, null,2));
|
|
27
26
|
return appConfig;
|
|
28
27
|
}
|
|
29
28
|
|
|
@@ -36,7 +35,7 @@ class PlatformManager extends PlatformManagerInterface {
|
|
|
36
35
|
*/
|
|
37
36
|
setTimezone(timezone) {
|
|
38
37
|
if (window.cefQuery) {
|
|
39
|
-
const request = {
|
|
38
|
+
const request = {message: JSON.stringify({type: "setTimeZone", timezone}), waitForResponse: false, target: "UI-Streamer"};
|
|
40
39
|
window.cefQuery({
|
|
41
40
|
request: JSON.stringify(request),
|
|
42
41
|
persistent: false,
|