senza-sdk 4.2.47 → 4.2.49
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 +1 -1
- package/src/alarmManager.js +79 -54
- package/src/api.js +10 -1
- package/src/eventListenersManager.js +108 -0
- package/src/lifecycle.js +153 -19
package/package.json
CHANGED
package/src/alarmManager.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getFCID, sdkLogger } from "./utils";
|
|
2
|
+
import { EventListenersManager } from "./eventListenersManager";
|
|
2
3
|
import { lifecycle } from "./lifecycle";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -25,71 +26,95 @@ class AlarmManager extends EventTarget {
|
|
|
25
26
|
*/
|
|
26
27
|
constructor() {
|
|
27
28
|
super();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Event listeners manager for alarm events
|
|
32
|
+
* @type {EventListenersManager}
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
this._eventManager = new EventListenersManager({
|
|
36
|
+
timeoutMs: 15000 // Default timeout of 15 seconds, can be overridden by _setDefaultTimeout
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
typeof document !== "undefined" && document.addEventListener("hs/alarmFiredEvent",async (e) => {
|
|
40
|
+
|
|
32
41
|
if (e.detail?.alarmName) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
42
|
+
const logger = sdkLogger.withFields({alarmName: e.detail?.alarmName});
|
|
43
|
+
logger.log("Got hs/alarmFiredEvent", JSON.stringify(e.detail));
|
|
44
|
+
|
|
45
|
+
const timeBeforeAlarmHandling = Date.now();
|
|
46
|
+
|
|
47
|
+
let sourceState;
|
|
48
|
+
if (lifecycle.state === lifecycle.UiState.FOREGROUND || lifecycle.state === lifecycle.UiState.IN_TRANSITION_TO_FOREGROUND) {
|
|
49
|
+
sourceState = "foreground";
|
|
50
|
+
} else {
|
|
51
|
+
sourceState = "background";
|
|
52
|
+
}
|
|
53
|
+
this._targetState = sourceState;
|
|
54
|
+
|
|
55
|
+
// Create the custom event with payload
|
|
56
|
+
const event = new CustomEvent(e.detail.alarmName, {detail: e.detail.payload});
|
|
57
|
+
|
|
58
|
+
// Dispatch the event and wait for all listeners
|
|
59
|
+
await this._eventManager.dispatch(e.detail.alarmName, event);
|
|
60
|
+
|
|
61
|
+
const alarmHandlingDuration = Date.now() - timeBeforeAlarmHandling;
|
|
62
|
+
logger.log(`All callbacks for alarm '${e.detail.alarmName}' are finished within ${alarmHandlingDuration}ms`);
|
|
63
|
+
// If this alarm triggered the application, and moveToForeground has not been called as a result of the alarm
|
|
64
|
+
// (i.e. the application is still in the background), we want to intentionally terminate the ui in order to save resources.
|
|
65
|
+
const isTriggering = lifecycle.triggerEvent.type === "alarmFiredEvent" && lifecycle._triggerEventFcid && lifecycle._triggerEventFcid === e.detail.fcid;
|
|
66
|
+
if (isTriggering) {
|
|
67
|
+
if (!this._moveToForegroundHasBeenCalled && window.cefQuery) {
|
|
68
|
+
logger.log("Application is about to be terminated since didn't move to foreground");
|
|
69
|
+
const message = { type: "terminating" };
|
|
70
|
+
const request = { target:"TC", waitForResponse: false, message: JSON.stringify(message) };
|
|
71
|
+
window.cefQuery({
|
|
72
|
+
request: JSON.stringify(request),
|
|
73
|
+
persistent: false,
|
|
74
|
+
onSuccess: () => {
|
|
75
|
+
logger.log("terminating request successfully sent");
|
|
76
|
+
},
|
|
77
|
+
onFailure: (code, msg) => {
|
|
78
|
+
logger.error(`terminating request failed: ${code} ${msg}`);
|
|
64
79
|
}
|
|
65
|
-
}
|
|
66
|
-
// For monitoring purposes, log a json with all the necessary labels and a unique prefix [hs-sdk][metrics]
|
|
67
|
-
// The ui-streamer will recognize this prefix and handle the json accordingly.
|
|
68
|
-
logger.metrics({
|
|
69
|
-
type: "monitorAlarm",
|
|
70
|
-
alarmName: e.detail.alarmName,
|
|
71
|
-
isTriggering,
|
|
72
|
-
sourceState,
|
|
73
|
-
targetState: this._targetState,
|
|
74
|
-
alarmHandlingDuration
|
|
75
80
|
});
|
|
76
|
-
}
|
|
81
|
+
}
|
|
77
82
|
}
|
|
83
|
+
// For monitoring purposes, log a json with all the necessary labels and a unique prefix [hs-sdk][metrics]
|
|
84
|
+
// The ui-streamer will recognize this prefix and handle the json accordingly.
|
|
85
|
+
logger.metrics({
|
|
86
|
+
type: "monitorAlarm",
|
|
87
|
+
alarmName: e.detail.alarmName,
|
|
88
|
+
isTriggering,
|
|
89
|
+
sourceState,
|
|
90
|
+
targetState: this._targetState,
|
|
91
|
+
alarmHandlingDuration
|
|
92
|
+
});
|
|
78
93
|
}
|
|
79
|
-
}
|
|
94
|
+
}
|
|
95
|
+
);
|
|
80
96
|
}
|
|
81
97
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Set the default timeout for alarm event listeners
|
|
100
|
+
* @param {number} timeout - Timeout in milliseconds for alarm event listeners
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
_setDefaultTimeout(timeout) {
|
|
104
|
+
if (typeof timeout === "number" && timeout > 0) {
|
|
105
|
+
this._eventManager.timeoutMs = timeout;
|
|
106
|
+
sdkLogger.log(`Alarm event listener timeout set to ${timeout}ms`);
|
|
107
|
+
} else {
|
|
108
|
+
sdkLogger.warn(`Invalid timeout value: ${timeout}. Must be a positive number.`);
|
|
85
109
|
}
|
|
86
|
-
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
addEventListener(type, callback) {
|
|
113
|
+
this._eventManager.addEventListener(type, callback);
|
|
87
114
|
}
|
|
88
115
|
|
|
89
116
|
removeEventListener(type, callback){
|
|
90
|
-
|
|
91
|
-
this._eventListeners[type].delete(callback);
|
|
92
|
-
}
|
|
117
|
+
this._eventManager.removeEventListener(type, callback);
|
|
93
118
|
}
|
|
94
119
|
|
|
95
120
|
_moveToForegroundCalled() {
|
package/src/api.js
CHANGED
|
@@ -4,6 +4,7 @@ import { sessionInfo } from "./SessionInfo";
|
|
|
4
4
|
const { version } = pack;
|
|
5
5
|
import { initSequence, showSequence } from "./devSequence.js";
|
|
6
6
|
import { lifecycle } from "./lifecycle";
|
|
7
|
+
import { alarmManager } from "./alarmManager";
|
|
7
8
|
|
|
8
9
|
let authToken;
|
|
9
10
|
|
|
@@ -110,6 +111,12 @@ export async function init() {
|
|
|
110
111
|
sdkLogger.log(`onUpdateSessionEvent: token = ${authToken}`);
|
|
111
112
|
});
|
|
112
113
|
|
|
114
|
+
// Set default alarm timeout using UI-Streamer settings
|
|
115
|
+
const alarmTimeout = sessionInfoObj?.settings?.["ui-streamer"]?.alarmTimeout;
|
|
116
|
+
if (alarmTimeout) {
|
|
117
|
+
alarmManager._setDefaultTimeout(alarmTimeout);
|
|
118
|
+
}
|
|
119
|
+
|
|
113
120
|
// Get trigger event
|
|
114
121
|
const triggerEventStr = await new Promise((resolve) => {
|
|
115
122
|
const FCID = getFCID();
|
|
@@ -157,6 +164,8 @@ export async function init() {
|
|
|
157
164
|
window.close = () => {
|
|
158
165
|
sdkLogger.warn("window.close is disabled on Senza platform. Use lifecycle.exitApplication() instead.");
|
|
159
166
|
};
|
|
167
|
+
|
|
168
|
+
|
|
160
169
|
}
|
|
161
170
|
|
|
162
171
|
/**
|
|
@@ -343,7 +352,7 @@ export function getDeviceInfo() {
|
|
|
343
352
|
export { lifecycle } from "./lifecycle";
|
|
344
353
|
export { deviceManager } from "./deviceManager";
|
|
345
354
|
export { platformManager } from "./platformManager";
|
|
346
|
-
export { alarmManager }
|
|
355
|
+
export { alarmManager };
|
|
347
356
|
export { messageManager } from "./messageManager";
|
|
348
357
|
export { initSequence, showSequence } from "./devSequence";
|
|
349
358
|
export { SenzaShakaPlayer as ShakaPlayer, shaka } from "./senzaShakaPlayer";
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { sdkLogger } from "./utils";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* EventListenersManager - A utility class to manage event listeners with Promise-based completion tracking
|
|
5
|
+
* Handles both synchronous and asynchronous listeners, with timeout support
|
|
6
|
+
*/
|
|
7
|
+
export class EventListenersManager {
|
|
8
|
+
/**
|
|
9
|
+
* Create a new EventListenersManager
|
|
10
|
+
* @param {Object} options - Configuration options
|
|
11
|
+
* @param {number} [options.timeoutMs=5000] - Timeout in milliseconds for each listener
|
|
12
|
+
*/
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.listeners = new Map(); // Map of event types to arrays of listeners
|
|
15
|
+
this.timeoutMs = options.timeoutMs || 5000;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Add an event listener for a specific event type
|
|
20
|
+
* @param {string} eventType - The type of event to listen for
|
|
21
|
+
* @param {Function} listener - The callback function
|
|
22
|
+
*/
|
|
23
|
+
addEventListener(eventType, listener) {
|
|
24
|
+
if (!this.listeners.has(eventType)) {
|
|
25
|
+
this.listeners.set(eventType, []);
|
|
26
|
+
}
|
|
27
|
+
this.listeners.get(eventType).push(listener);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Remove an event listener for a specific event type
|
|
32
|
+
* @param {string} eventType - The type of event
|
|
33
|
+
* @param {Function} listener - The callback function to remove
|
|
34
|
+
*/
|
|
35
|
+
removeEventListener(eventType, listener) {
|
|
36
|
+
if (!this.listeners.has(eventType)) return;
|
|
37
|
+
|
|
38
|
+
const listenerArray = this.listeners.get(eventType);
|
|
39
|
+
const index = listenerArray.indexOf(listener);
|
|
40
|
+
if (index !== -1) {
|
|
41
|
+
listenerArray.splice(index, 1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Dispatch an event and wait for all listeners to complete
|
|
48
|
+
* @param {string} eventType - The type of event to dispatch
|
|
49
|
+
* @param {*} eventDetail - The event detail or Event object to pass to listeners
|
|
50
|
+
* @returns {Promise<void>} A promise that resolves when all listeners have completed
|
|
51
|
+
*/
|
|
52
|
+
async dispatch(eventType, eventDetail = {}){
|
|
53
|
+
const eventListeners = this.listeners.get(eventType) || [];
|
|
54
|
+
|
|
55
|
+
if (eventListeners.length === 0) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Create event object if eventDetail isn't already an Event
|
|
60
|
+
const event = eventDetail instanceof Event ? eventDetail : new CustomEvent(eventType, { detail: eventDetail });
|
|
61
|
+
|
|
62
|
+
// Execute all listeners and wrap each in a safe promise that won't reject
|
|
63
|
+
const listenerPromises = eventListeners.map(listener => {
|
|
64
|
+
try {
|
|
65
|
+
return Promise.resolve(listener(event))
|
|
66
|
+
.catch(error => {
|
|
67
|
+
sdkLogger.error(`Error in ${eventType} listener (promise rejection):`, error);
|
|
68
|
+
return undefined; // Convert rejected promises to resolved promises
|
|
69
|
+
});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
sdkLogger.error(`Error in ${eventType} listener:`, error);
|
|
72
|
+
return Promise.resolve(); // Continue with other listeners even if one fails
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
// Create a timeout timer we can cancel
|
|
78
|
+
let timeoutId = null;
|
|
79
|
+
|
|
80
|
+
// Create a single timeout promise for the entire batch
|
|
81
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
82
|
+
timeoutId = setTimeout(() => {
|
|
83
|
+
sdkLogger.warn(`Event dispatch for ${eventType} timed out after ${this.timeoutMs}ms`);
|
|
84
|
+
resolve();
|
|
85
|
+
}, this.timeoutMs);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Create a promise for all listeners completing
|
|
89
|
+
const allListenersPromise = Promise.allSettled(listenerPromises).then(results => {
|
|
90
|
+
// Clear the timeout when all listeners complete
|
|
91
|
+
if (timeoutId !== null) {
|
|
92
|
+
clearTimeout(timeoutId);
|
|
93
|
+
timeoutId = null;
|
|
94
|
+
}
|
|
95
|
+
return results;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Race between all listeners completing and the timeout
|
|
99
|
+
await Promise.race([allListenersPromise, timeoutPromise]);
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
} catch (error) {
|
|
103
|
+
sdkLogger.error(`Error waiting for ${eventType} listeners to complete:`, error);
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
}
|
package/src/lifecycle.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
SenzaError,
|
|
10
10
|
TargetPlayingState
|
|
11
11
|
} from "./utils";
|
|
12
|
+
import { EventListenersManager } from "./eventListenersManager";
|
|
12
13
|
import { sessionInfo } from "./SessionInfo";
|
|
13
14
|
import { DEFAULT_REMOTE_PLAYER_CONFIRMATION_TIMEOUT, remotePlayer } from "./remotePlayer";
|
|
14
15
|
|
|
@@ -103,6 +104,15 @@ class Lifecycle extends EventTarget {
|
|
|
103
104
|
this._isInitialized = false;
|
|
104
105
|
this._inTransition = false;
|
|
105
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Event listeners manager for the userdisconnected event
|
|
109
|
+
* @type {EventListenersManager}
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
this._eventManager = new EventListenersManager({
|
|
113
|
+
timeoutMs: 10000
|
|
114
|
+
});
|
|
115
|
+
|
|
106
116
|
/**
|
|
107
117
|
* @type {boolean}
|
|
108
118
|
* @private
|
|
@@ -139,9 +149,14 @@ class Lifecycle extends EventTarget {
|
|
|
139
149
|
this.dispatchEvent(event);
|
|
140
150
|
});
|
|
141
151
|
|
|
142
|
-
typeof document !== "undefined" && document.addEventListener("hs/endOfSession", () => {
|
|
152
|
+
typeof document !== "undefined" && document.addEventListener("hs/endOfSession", async () => {
|
|
153
|
+
// Create the event
|
|
143
154
|
const event = new Event("userdisconnected");
|
|
144
|
-
|
|
155
|
+
|
|
156
|
+
// Use the event manager to dispatch the event and wait for all listeners
|
|
157
|
+
await this._eventManager.dispatch("userdisconnected", event);
|
|
158
|
+
|
|
159
|
+
this._sendTerminatingMessage();
|
|
145
160
|
});
|
|
146
161
|
|
|
147
162
|
typeof document !== "undefined" && document.addEventListener("keydown", () => {
|
|
@@ -167,9 +182,10 @@ class Lifecycle extends EventTarget {
|
|
|
167
182
|
/** @private Initialize the lifecycle
|
|
168
183
|
* @param {Object} uiStreamerSettings - UI-streamer portion of the settings taken from session info
|
|
169
184
|
* @param {Object} [uiStreamerSettings.autoBackground] - Auto background mode configuration
|
|
170
|
-
* @param {boolean} [uiStreamerSettings.autoBackground.
|
|
171
|
-
* @param {
|
|
172
|
-
* @param {number} [uiStreamerSettings.autoBackground.
|
|
185
|
+
* @param {boolean} [uiStreamerSettings.autoBackground.enabled=false] - Enable/disable auto background
|
|
186
|
+
* @param {Object} [uiStreamerSettings.autoBackground.timeout] - Timeout settings
|
|
187
|
+
* @param {number|false} [uiStreamerSettings.autoBackground.timeout.playing=30] - Timeout in seconds when video is playing, false to disable
|
|
188
|
+
* @param {number|false} [uiStreamerSettings.autoBackground.timeout.idle=false] - Timeout in seconds when in UI mode, false to disable
|
|
173
189
|
* @param {number} [uiStreamerSettings.remotePlayerConfirmationTimeout=5000] - Timeout in milliseconds for remote player operations
|
|
174
190
|
* @param {number} [uiStreamerSettings.remotePlayerApiVersion=1] - Remote player API version
|
|
175
191
|
*/
|
|
@@ -246,23 +262,83 @@ class Lifecycle extends EventTarget {
|
|
|
246
262
|
this._remotePlayerConfirmationTimeout = uiStreamerSettings?.remotePlayerConfirmationTimeout ?? DEFAULT_REMOTE_PLAYER_CONFIRMATION_TIMEOUT;
|
|
247
263
|
this._remotePlayerApiVersion = uiStreamerSettings?.remotePlayerApiVersion || 1;
|
|
248
264
|
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
265
|
+
// Apply autoBackground settings if provided
|
|
266
|
+
if (uiStreamerSettings?.autoBackground) {
|
|
267
|
+
this.configure({
|
|
268
|
+
autoBackground: uiStreamerSettings.autoBackground
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Configure lifecycle settings
|
|
276
|
+
* @param {Object} config - Configuration object
|
|
277
|
+
* @param {Object} [config.autoBackground] - Auto background settings
|
|
278
|
+
* @param {boolean} [config.autoBackground.enabled] - Enable/disable auto background
|
|
279
|
+
* @param {Object} [config.autoBackground.timeout] - Timeout settings
|
|
280
|
+
* @param {number|false} [config.autoBackground.timeout.playing=30] - Timeout in seconds when video is playing, false to disable
|
|
281
|
+
* @param {number|false} [config.autoBackground.timeout.idle=false] - Timeout in seconds when in UI mode, false to disable
|
|
282
|
+
*/
|
|
283
|
+
configure(config) {
|
|
284
|
+
if (config?.autoBackground) {
|
|
285
|
+
const { enabled, timeout } = config.autoBackground;
|
|
286
|
+
|
|
287
|
+
// Update enabled state
|
|
288
|
+
if (typeof enabled === "boolean") {
|
|
289
|
+
this._autoBackground = enabled;
|
|
290
|
+
}
|
|
291
|
+
// Update timeouts
|
|
292
|
+
if (timeout) {
|
|
293
|
+
if (timeout.playing !== undefined) {
|
|
294
|
+
if (timeout.playing === false) {
|
|
295
|
+
this._autoBackgroundOnVideoDelay = -1;
|
|
296
|
+
} else if (typeof timeout.playing === "number") {
|
|
297
|
+
this._autoBackgroundOnVideoDelay = timeout.playing;
|
|
298
|
+
} else {
|
|
299
|
+
sdkLogger.warn("Invalid autoBackground.timeout.playing value, expected number or false");
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (timeout.idle !== undefined) {
|
|
303
|
+
if (timeout.idle === false) {
|
|
304
|
+
this._autoBackgroundOnUIDelay = -1;
|
|
305
|
+
} else if (typeof timeout.idle === "number") {
|
|
306
|
+
this._autoBackgroundOnUIDelay = timeout.idle;
|
|
307
|
+
} else {
|
|
308
|
+
sdkLogger.warn("Invalid autoBackground.timeout.idle value, expected number or false");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Start or stop countdown based on new configuration
|
|
313
|
+
if (this._autoBackground) {
|
|
261
314
|
this._startCountdown();
|
|
262
|
-
}
|
|
315
|
+
} else {
|
|
316
|
+
this._stopCountdown();
|
|
317
|
+
}
|
|
263
318
|
}
|
|
264
319
|
}
|
|
265
320
|
|
|
321
|
+
/**
|
|
322
|
+
* Get the current configuration settings
|
|
323
|
+
* @returns {Object} The current configuration object
|
|
324
|
+
* @example
|
|
325
|
+
* const config = lifecycle.getConfiguration();
|
|
326
|
+
* console.log(config.autoBackground.enabled); // true/false
|
|
327
|
+
* console.log(config.autoBackground.timeout.playing); // 30
|
|
328
|
+
* console.log(config.autoBackground.timeout.idle); // false
|
|
329
|
+
*/
|
|
330
|
+
getConfiguration() {
|
|
331
|
+
return {
|
|
332
|
+
autoBackground: {
|
|
333
|
+
enabled: this._autoBackground,
|
|
334
|
+
timeout: {
|
|
335
|
+
playing: this._autoBackgroundOnVideoDelay <= 0 ? false : this._autoBackgroundOnVideoDelay,
|
|
336
|
+
idle: this._autoBackgroundOnUIDelay <= 0 ? false : this._autoBackgroundOnUIDelay
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
266
342
|
/**
|
|
267
343
|
* This method moves the application into standby mode, i.e. last ui frame is displayed and ui resources are released.
|
|
268
344
|
* It should be called whenever the application wishes to go into standby mode and release resources.
|
|
@@ -396,10 +472,10 @@ class Lifecycle extends EventTarget {
|
|
|
396
472
|
this._stopCountdown();
|
|
397
473
|
|
|
398
474
|
const timeoutDelay = isPlaying ? this._autoBackgroundOnVideoDelay : this._autoBackgroundOnUIDelay;
|
|
399
|
-
sdkLogger.debug("Starting countdown timeout", timeoutDelay, isPlaying ? "(video)" : "(UI)");
|
|
400
475
|
|
|
401
476
|
// Only start countdown if delay is positive
|
|
402
477
|
if (timeoutDelay > 0) {
|
|
478
|
+
sdkLogger.debug("Starting countdown timeout", timeoutDelay, isPlaying ? "(video)" : "(UI)");
|
|
403
479
|
this._countdown = setTimeout(() => {
|
|
404
480
|
sdkLogger.debug("Countdown timeout reached, moving to background");
|
|
405
481
|
this.moveToBackground();
|
|
@@ -746,6 +822,64 @@ class Lifecycle extends EventTarget {
|
|
|
746
822
|
sdkLogger.warn("exitApplication is not supported if NOT running e2e");
|
|
747
823
|
return Promise.reject("exitApplication is not supported if NOT running e2e");
|
|
748
824
|
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Override addEventListener to handle "userdisconnected" event specially
|
|
828
|
+
* @param {string} type - The event type to listen for
|
|
829
|
+
* @param {Function} listener - The callback function
|
|
830
|
+
* @param {Object} options - Event listener options
|
|
831
|
+
*/
|
|
832
|
+
addEventListener(type, listener, options) {
|
|
833
|
+
if (type === "userdisconnected") {
|
|
834
|
+
// Use the event manager for userdisconnected events
|
|
835
|
+
this._eventManager.addEventListener(type, listener);
|
|
836
|
+
} else {
|
|
837
|
+
// For all other event types, use the parent class implementation
|
|
838
|
+
super.addEventListener(type, listener, options);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* Override removeEventListener to handle "userdisconnected" event specially
|
|
844
|
+
* @param {string} type - The event type
|
|
845
|
+
* @param {Function} listener - The callback function to remove
|
|
846
|
+
* @param {Object} options - Event listener options
|
|
847
|
+
*/
|
|
848
|
+
removeEventListener(type, listener, options) {
|
|
849
|
+
if (type === "userdisconnected") {
|
|
850
|
+
// Use the event manager for userdisconnected events
|
|
851
|
+
this._eventManager.removeEventListener(type, listener);
|
|
852
|
+
} else {
|
|
853
|
+
// For all other event types, use the parent class implementation
|
|
854
|
+
super.removeEventListener(type, listener, options);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Sends the terminating message to the platform
|
|
860
|
+
* @private
|
|
861
|
+
*/
|
|
862
|
+
_sendTerminatingMessage() {
|
|
863
|
+
if (window.cefQuery) {
|
|
864
|
+
const FCID = getFCID();
|
|
865
|
+
const message = {
|
|
866
|
+
type: "terminating",
|
|
867
|
+
fcid: FCID
|
|
868
|
+
};
|
|
869
|
+
const request = { target: "TC", waitForResponse: false, message: JSON.stringify(message) };
|
|
870
|
+
|
|
871
|
+
window.cefQuery({
|
|
872
|
+
request: JSON.stringify(request),
|
|
873
|
+
persistent: false,
|
|
874
|
+
onSuccess: () => {
|
|
875
|
+
sdkLogger.log("Terminating signal sent after userdisconnected event was processed");
|
|
876
|
+
},
|
|
877
|
+
onFailure: (code, msg) => {
|
|
878
|
+
sdkLogger.error(`Failed to send terminating signal: ${code} ${msg}`);
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
}
|
|
749
883
|
}
|
|
750
884
|
|
|
751
885
|
/**
|