senza-sdk 4.4.5 → 4.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -17,9 +17,15 @@ import { DEFAULT_REMOTE_PLAYER_CONFIRMATION_TIMEOUT, remotePlayer } from "./remo
|
|
|
17
17
|
import {bus, Events} from "./eventBus";
|
|
18
18
|
|
|
19
19
|
// Default values for autoBackground settings. These values are used if the UIStreamer settings are not provided.
|
|
20
|
-
const DEFAULT_AUTO_BACKGROUND_VIDEO_DELAY =
|
|
21
|
-
const DEFAULT_AUTO_BACKGROUND_UI_DELAY =
|
|
22
|
-
const DEFAULT_AUTO_BACKGROUND_ENABLED =
|
|
20
|
+
const DEFAULT_AUTO_BACKGROUND_VIDEO_DELAY = 10*60;
|
|
21
|
+
const DEFAULT_AUTO_BACKGROUND_UI_DELAY = 10*60;
|
|
22
|
+
const DEFAULT_AUTO_BACKGROUND_ENABLED = true;
|
|
23
|
+
// Default values for autoSuspend settings
|
|
24
|
+
const DEFAULT_AUTO_SUSPEND_ENABLED = false;
|
|
25
|
+
const DEFAULT_AUTO_SUSPEND_PLAYING_DELAY = 60;
|
|
26
|
+
const DEFAULT_AUTO_SUSPEND_IDLE_DELAY = 60;
|
|
27
|
+
// Session storage key for tracking timer-triggered background state
|
|
28
|
+
const BACKGROUND_TIMER_KEY = "senzaSDK_backgroundTriggeredByTimer";
|
|
23
29
|
|
|
24
30
|
class Lifecycle extends LifecycleInterface {
|
|
25
31
|
constructor() {
|
|
@@ -60,6 +66,81 @@ class Lifecycle extends LifecycleInterface {
|
|
|
60
66
|
* @private
|
|
61
67
|
*/
|
|
62
68
|
this._autoBackgroundOnUIDelay = DEFAULT_AUTO_BACKGROUND_UI_DELAY;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Timestamp of the last user activity
|
|
72
|
+
* @type {number}
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
this._lastActivityTimestamp = Date.now();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Auto suspend configuration
|
|
79
|
+
* @type {Object}
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
this._autoSuspend = {
|
|
83
|
+
enabled: DEFAULT_AUTO_SUSPEND_ENABLED,
|
|
84
|
+
timeout: {
|
|
85
|
+
playing: DEFAULT_AUTO_SUSPEND_PLAYING_DELAY,
|
|
86
|
+
idle: DEFAULT_AUTO_SUSPEND_IDLE_DELAY
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Timer for auto suspend functionality
|
|
92
|
+
* @type {number|null}
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
this._suspendCountdown = null;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Timestamp when the application entered background state
|
|
99
|
+
* @type {number}
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
this._backgroundTimestamp = Date.now();
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Flag to track if suspend was triggered by timer
|
|
106
|
+
* @type {boolean}
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
this._isSuspendTriggeredByTimer = false;
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @private Gets the background triggered by timer flag from sessionStorage
|
|
115
|
+
* @returns {boolean}
|
|
116
|
+
*/
|
|
117
|
+
get _isBackgroundTriggeredByTimer() {
|
|
118
|
+
try {
|
|
119
|
+
const value = typeof window !== "undefined" && window.sessionStorage ?
|
|
120
|
+
window.sessionStorage.getItem(BACKGROUND_TIMER_KEY) : null;
|
|
121
|
+
return value === "true";
|
|
122
|
+
} catch (error) {
|
|
123
|
+
sdkLogger.warn("Failed to read _isBackgroundTriggeredByTimer from sessionStorage:", error);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @private Sets the background triggered by timer flag in sessionStorage
|
|
130
|
+
* @param {boolean} value
|
|
131
|
+
*/
|
|
132
|
+
set _isBackgroundTriggeredByTimer(value) {
|
|
133
|
+
try {
|
|
134
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
135
|
+
if (value) {
|
|
136
|
+
window.sessionStorage.setItem(BACKGROUND_TIMER_KEY, "true");
|
|
137
|
+
} else {
|
|
138
|
+
window.sessionStorage.removeItem(BACKGROUND_TIMER_KEY);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} catch (error) {
|
|
142
|
+
sdkLogger.warn("Failed to write _backgroundTriggeredByTimer to sessionStorage:", error);
|
|
143
|
+
}
|
|
63
144
|
}
|
|
64
145
|
|
|
65
146
|
// List of event types that should use the _eventManager
|
|
@@ -76,6 +157,11 @@ class Lifecycle extends LifecycleInterface {
|
|
|
76
157
|
* @param {Object} [uiStreamerSettings.autoBackground.timeout] - Timeout settings
|
|
77
158
|
* @param {number|false} [uiStreamerSettings.autoBackground.timeout.playing=30] - Timeout in seconds when video is playing, false to disable
|
|
78
159
|
* @param {number|false} [uiStreamerSettings.autoBackground.timeout.idle=false] - Timeout in seconds when in UI mode, false to disable
|
|
160
|
+
* @param {Object} [uiStreamerSettings.autoSuspend] - Auto suspend mode configuration
|
|
161
|
+
* @param {boolean} [uiStreamerSettings.autoSuspend.enabled=false] - Enable/disable auto suspend
|
|
162
|
+
* @param {Object} [uiStreamerSettings.autoSuspend.timeout] - Timeout settings
|
|
163
|
+
* @param {number} [uiStreamerSettings.autoSuspend.timeout.playing=60] - Timeout in seconds when video is playing
|
|
164
|
+
* @param {number} [uiStreamerSettings.autoSuspend.timeout.idle=60] - Timeout in seconds when in idle mode
|
|
79
165
|
* @param {number} [uiStreamerSettings.remotePlayerConfirmationTimeout=5000] - Timeout in milliseconds for remote player operations
|
|
80
166
|
* @param {number} [uiStreamerSettings.remotePlayerApiVersion=1] - Remote player API version
|
|
81
167
|
*/
|
|
@@ -171,6 +257,13 @@ class Lifecycle extends LifecycleInterface {
|
|
|
171
257
|
autoBackground: uiStreamerSettings.autoBackground
|
|
172
258
|
});
|
|
173
259
|
}
|
|
260
|
+
|
|
261
|
+
// Apply autoSuspend settings if provided
|
|
262
|
+
if (uiStreamerSettings?.autoSuspend) {
|
|
263
|
+
this.configure({
|
|
264
|
+
autoSuspend: uiStreamerSettings.autoSuspend
|
|
265
|
+
});
|
|
266
|
+
}
|
|
174
267
|
}
|
|
175
268
|
}
|
|
176
269
|
|
|
@@ -186,6 +279,17 @@ class Lifecycle extends LifecycleInterface {
|
|
|
186
279
|
if (this._isAutoBackgroundEnabled() && this._isForegroundOrTransitioning()) {
|
|
187
280
|
this._startCountdown();
|
|
188
281
|
}
|
|
282
|
+
// Track timestamp when entering background state
|
|
283
|
+
if (this._state === this.UiState.BACKGROUND) {
|
|
284
|
+
this._backgroundTimestamp = Date.now();
|
|
285
|
+
}
|
|
286
|
+
// Start suspend countdown when entering background state
|
|
287
|
+
if (this._isAutoSuspendEnabled() && this._state === this.UiState.BACKGROUND) {
|
|
288
|
+
this._startSuspendCountdown();
|
|
289
|
+
} else {
|
|
290
|
+
// Stop suspend countdown when leaving background state
|
|
291
|
+
this._stopSuspendCountdown();
|
|
292
|
+
}
|
|
189
293
|
this.dispatchEvent(event);
|
|
190
294
|
});
|
|
191
295
|
|
|
@@ -207,9 +311,14 @@ class Lifecycle extends LifecycleInterface {
|
|
|
207
311
|
});
|
|
208
312
|
|
|
209
313
|
typeof document !== "undefined" && document.addEventListener("keydown", () => {
|
|
314
|
+
// Track the timestamp of the last user activity
|
|
315
|
+
this._lastActivityTimestamp = Date.now();
|
|
316
|
+
|
|
210
317
|
if (this._isAutoBackgroundEnabled()) {
|
|
211
|
-
|
|
212
|
-
|
|
318
|
+
|
|
319
|
+
if (this._isBackgroundTriggeredByTimer && (this.state === this.UiState.BACKGROUND ||
|
|
320
|
+
this.state === this.UiState.IN_TRANSITION_TO_BACKGROUND)) {
|
|
321
|
+
sdkLogger.log("Moving to foreground due to user interaction after auto background");
|
|
213
322
|
this.moveToForeground();
|
|
214
323
|
} else {
|
|
215
324
|
this._startCountdown();
|
|
@@ -223,6 +332,11 @@ class Lifecycle extends LifecycleInterface {
|
|
|
223
332
|
sdkLogger.log("Resetting auto background timer due to play mode change", event.detail.isPlaying);
|
|
224
333
|
this._startCountdown(event.detail.isPlaying);
|
|
225
334
|
}
|
|
335
|
+
// Also restart suspend countdown if in background state
|
|
336
|
+
if (this._isAutoSuspendEnabled() && this._state === this.UiState.BACKGROUND) {
|
|
337
|
+
sdkLogger.log("Resetting auto suspend timer due to play mode change", event.detail.isPlaying);
|
|
338
|
+
this._startSuspendCountdown(event.detail.isPlaying);
|
|
339
|
+
}
|
|
226
340
|
});
|
|
227
341
|
sdkLogger.log("[Lifecycle] Added event listeners for system events");
|
|
228
342
|
}
|
|
@@ -267,6 +381,30 @@ class Lifecycle extends LifecycleInterface {
|
|
|
267
381
|
return this._autoBackgroundOnUIDelay;
|
|
268
382
|
}
|
|
269
383
|
|
|
384
|
+
/**
|
|
385
|
+
* @private Checks if auto suspend is enabled.
|
|
386
|
+
* @returns {boolean}
|
|
387
|
+
*/
|
|
388
|
+
_isAutoSuspendEnabled() {
|
|
389
|
+
return this._autoSuspend.enabled;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* @private Gets the auto suspend playing delay.
|
|
394
|
+
* @returns {number}
|
|
395
|
+
*/
|
|
396
|
+
_getAutoSuspendOnPlayingDelay() {
|
|
397
|
+
return this._autoSuspend.timeout.playing;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* @private Gets the auto suspend idle delay.
|
|
402
|
+
* @returns {number}
|
|
403
|
+
*/
|
|
404
|
+
_getAutoSuspendOnIdleDelay() {
|
|
405
|
+
return this._autoSuspend.timeout.idle;
|
|
406
|
+
}
|
|
407
|
+
|
|
270
408
|
configure(config) {
|
|
271
409
|
if (config?.autoBackground) {
|
|
272
410
|
const { enabled, timeout } = config.autoBackground;
|
|
@@ -304,6 +442,39 @@ class Lifecycle extends LifecycleInterface {
|
|
|
304
442
|
this._stopCountdown();
|
|
305
443
|
}
|
|
306
444
|
}
|
|
445
|
+
|
|
446
|
+
if (config?.autoSuspend) {
|
|
447
|
+
const { enabled, timeout } = config.autoSuspend;
|
|
448
|
+
|
|
449
|
+
// Update enabled state
|
|
450
|
+
if (typeof enabled === "boolean") {
|
|
451
|
+
this._autoSuspend.enabled = enabled;
|
|
452
|
+
}
|
|
453
|
+
// Update timeouts
|
|
454
|
+
if (timeout) {
|
|
455
|
+
if (timeout.playing !== undefined) {
|
|
456
|
+
if (typeof timeout.playing === "number") {
|
|
457
|
+
this._autoSuspend.timeout.playing = timeout.playing;
|
|
458
|
+
} else {
|
|
459
|
+
sdkLogger.warn("Invalid autoSuspend.timeout.playing value, expected number");
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (timeout.idle !== undefined) {
|
|
463
|
+
if (typeof timeout.idle === "number") {
|
|
464
|
+
this._autoSuspend.timeout.idle = timeout.idle;
|
|
465
|
+
} else {
|
|
466
|
+
sdkLogger.warn("Invalid autoSuspend.timeout.idle value, expected number");
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Start or stop suspend countdown based on new configuration
|
|
472
|
+
if (this._isAutoSuspendEnabled() && this._state === this.UiState.BACKGROUND) {
|
|
473
|
+
this._startSuspendCountdown();
|
|
474
|
+
} else {
|
|
475
|
+
this._stopSuspendCountdown();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
307
478
|
}
|
|
308
479
|
|
|
309
480
|
getConfiguration() {
|
|
@@ -314,6 +485,13 @@ class Lifecycle extends LifecycleInterface {
|
|
|
314
485
|
playing: this._autoBackgroundOnVideoDelay <= 0 ? false : this._autoBackgroundOnVideoDelay,
|
|
315
486
|
idle: this._autoBackgroundOnUIDelay <= 0 ? false : this._autoBackgroundOnUIDelay
|
|
316
487
|
}
|
|
488
|
+
},
|
|
489
|
+
autoSuspend: {
|
|
490
|
+
enabled: this._autoSuspend.enabled,
|
|
491
|
+
timeout: {
|
|
492
|
+
playing: this._autoSuspend.timeout.playing,
|
|
493
|
+
idle: this._autoSuspend.timeout.idle
|
|
494
|
+
}
|
|
317
495
|
}
|
|
318
496
|
};
|
|
319
497
|
}
|
|
@@ -438,8 +616,9 @@ class Lifecycle extends LifecycleInterface {
|
|
|
438
616
|
this._startCountdown();
|
|
439
617
|
}
|
|
440
618
|
} else {
|
|
441
|
-
this.moveToBackground();
|
|
619
|
+
this.moveToBackground(true);
|
|
442
620
|
}
|
|
621
|
+
|
|
443
622
|
}, timeoutDelay * 1000);
|
|
444
623
|
} else {
|
|
445
624
|
sdkLogger.debug("Countdown not started - delay is negative or zero");
|
|
@@ -457,6 +636,68 @@ class Lifecycle extends LifecycleInterface {
|
|
|
457
636
|
}
|
|
458
637
|
}
|
|
459
638
|
|
|
639
|
+
/**
|
|
640
|
+
* @private Start the suspend countdown timer when in background state
|
|
641
|
+
*/
|
|
642
|
+
_startSuspendCountdown(isPlaying = remotePlayer._isPlaying) {
|
|
643
|
+
this._stopSuspendCountdown();
|
|
644
|
+
|
|
645
|
+
// Only start if we're in background state and auto suspend is enabled
|
|
646
|
+
if (this._state !== this.UiState.BACKGROUND || !this._isAutoSuspendEnabled()) {
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const timeoutDelay = isPlaying ? this._getAutoSuspendOnPlayingDelay() : this._getAutoSuspendOnIdleDelay();
|
|
651
|
+
|
|
652
|
+
// Only start countdown if delay is positive
|
|
653
|
+
if (timeoutDelay > 0) {
|
|
654
|
+
sdkLogger.debug("Starting suspend countdown timeout", timeoutDelay, isPlaying ? "(playing)" : "(idle)");
|
|
655
|
+
this._suspendCountdown = setTimeout(async () => {
|
|
656
|
+
sdkLogger.debug("Suspend countdown timeout reached, moving to suspended");
|
|
657
|
+
if (this._state === this.UiState.BACKGROUND) {
|
|
658
|
+
// Create the event with cancelable: true
|
|
659
|
+
const event = new Event("beforestatechange", { cancelable: true });
|
|
660
|
+
event.state = this.UiState.SUSPENDED;
|
|
661
|
+
// Use the event manager to dispatch the event and wait for all listeners
|
|
662
|
+
await this._eventManager.dispatch("beforestatechange", event);
|
|
663
|
+
// Check if any listener called preventDefault()
|
|
664
|
+
if (event.defaultPrevented) {
|
|
665
|
+
sdkLogger.info("moveToSuspended was prevented by a listener");
|
|
666
|
+
// Restart the suspend countdown since the move was cancelled
|
|
667
|
+
this._startSuspendCountdown();
|
|
668
|
+
} else {
|
|
669
|
+
try {
|
|
670
|
+
// Set flag to indicate suspend was triggered by timer
|
|
671
|
+
this._isSuspendTriggeredByTimer = true;
|
|
672
|
+
await this.moveToSuspended();
|
|
673
|
+
} catch (error) {
|
|
674
|
+
sdkLogger.error("Failed to move to suspended:", error);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
} else {
|
|
679
|
+
sdkLogger.warn("suspend timer was called while not in background");
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
}, timeoutDelay * 1000);
|
|
683
|
+
} else {
|
|
684
|
+
sdkLogger.debug("Suspend countdown not started - delay is zero or negative");
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @private Stop the suspend countdown timer
|
|
690
|
+
*/
|
|
691
|
+
_stopSuspendCountdown() {
|
|
692
|
+
if (this._suspendCountdown) {
|
|
693
|
+
sdkLogger.debug("Stopping suspend countdown timer");
|
|
694
|
+
clearTimeout(this._suspendCountdown);
|
|
695
|
+
this._suspendCountdown = null;
|
|
696
|
+
// Reset the timer flag when stopping countdown
|
|
697
|
+
this._isSuspendTriggeredByTimer = false;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
460
701
|
/**
|
|
461
702
|
* @private
|
|
462
703
|
*/
|
|
@@ -486,6 +727,12 @@ class Lifecycle extends LifecycleInterface {
|
|
|
486
727
|
}
|
|
487
728
|
|
|
488
729
|
moveToForeground() {
|
|
730
|
+
// Reset activity timestamp when moving to foreground
|
|
731
|
+
this._lastActivityTimestamp = Date.now();
|
|
732
|
+
|
|
733
|
+
// Clear the timer-triggered background flag when moving to foreground
|
|
734
|
+
this._isBackgroundTriggeredByTimer = false;
|
|
735
|
+
|
|
489
736
|
if (window.cefQuery) {
|
|
490
737
|
const inTransition = this._isInTransition();
|
|
491
738
|
if (inTransition || this._isForegroundOrTransitioning()) {
|
|
@@ -566,6 +813,16 @@ class Lifecycle extends LifecycleInterface {
|
|
|
566
813
|
}
|
|
567
814
|
|
|
568
815
|
_moveToBackground() {
|
|
816
|
+
// Report metrics for time since last user activity when moving to background
|
|
817
|
+
|
|
818
|
+
const duration = (Date.now() - this._lastActivityTimestamp)/1000;
|
|
819
|
+
|
|
820
|
+
sdkLogger.metrics({
|
|
821
|
+
type: "backgroundTransitions",
|
|
822
|
+
isAutoBackground: this._isBackgroundTriggeredByTimer,
|
|
823
|
+
isPlaying: remotePlayer._isPlaying,
|
|
824
|
+
duration
|
|
825
|
+
});
|
|
569
826
|
if (window.cefQuery) {
|
|
570
827
|
// If audio sync is disabled, we only need to sync before remote player starts playing
|
|
571
828
|
if (!isAudioSyncConfigured()) {
|
|
@@ -629,6 +886,8 @@ class Lifecycle extends LifecycleInterface {
|
|
|
629
886
|
const duration = Date.now() - timeBeforeSendingRequest;
|
|
630
887
|
logger.withFields({ duration }).log(`play failed after ${duration} ms. Error code: ${code}, error message: ${msg}`);
|
|
631
888
|
this._inTransitionToBackground = false;
|
|
889
|
+
// Clear the timer flag even if the transition fails
|
|
890
|
+
this._isBackgroundTriggeredByTimer = false;
|
|
632
891
|
timerId = clearTimer(timerId);
|
|
633
892
|
reject(new SenzaError(code, msg));
|
|
634
893
|
}
|
|
@@ -639,6 +898,8 @@ class Lifecycle extends LifecycleInterface {
|
|
|
639
898
|
timerId = setTimeout(() => {
|
|
640
899
|
logger.log(`play reached timeout of ${timeout} ms, canceling query id ${queryId}`);
|
|
641
900
|
this._inTransitionToBackground = false;
|
|
901
|
+
// Clear the timer flag even if the transition times out
|
|
902
|
+
this._isBackgroundTriggeredByTimer = false;
|
|
642
903
|
window.cefQueryCancel(queryId);
|
|
643
904
|
reject(new SenzaError(6000, `play reached timeout of ${timeout} ms`));
|
|
644
905
|
}, timeout, queryId);
|
|
@@ -649,7 +910,11 @@ class Lifecycle extends LifecycleInterface {
|
|
|
649
910
|
return Promise.resolve(false);
|
|
650
911
|
}
|
|
651
912
|
|
|
652
|
-
moveToBackground() {
|
|
913
|
+
moveToBackground(isTriggeredByTimer = false) {
|
|
914
|
+
|
|
915
|
+
// If the background transition is triggered by the auto background timer, set the flag
|
|
916
|
+
this._isBackgroundTriggeredByTimer = isTriggeredByTimer;
|
|
917
|
+
|
|
653
918
|
if (window.cefQuery) {
|
|
654
919
|
const inTransition = this._isInTransition();
|
|
655
920
|
if (inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
|
|
@@ -800,6 +1065,60 @@ class Lifecycle extends LifecycleInterface {
|
|
|
800
1065
|
return Promise.reject("disconnect is not supported if NOT running e2e");
|
|
801
1066
|
}
|
|
802
1067
|
|
|
1068
|
+
moveToSuspended() {
|
|
1069
|
+
// Check if the current state is BACKGROUND
|
|
1070
|
+
if (this._state !== this.UiState.BACKGROUND) {
|
|
1071
|
+
const errorMsg = `moveToSuspended can only be called from BACKGROUND state. Current state: ${this._state}`;
|
|
1072
|
+
sdkLogger.error(errorMsg);
|
|
1073
|
+
return Promise.reject(errorMsg);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// Report metrics for time between background and suspend
|
|
1077
|
+
const duration = (Date.now() - this._backgroundTimestamp) / 1000;
|
|
1078
|
+
|
|
1079
|
+
sdkLogger.metrics({
|
|
1080
|
+
type: "suspendTransitions",
|
|
1081
|
+
isAutoSuspend: this._isSuspendTriggeredByTimer,
|
|
1082
|
+
isPlaying: remotePlayer._isPlaying,
|
|
1083
|
+
duration
|
|
1084
|
+
});
|
|
1085
|
+
|
|
1086
|
+
// Reset the timer flag after reporting metrics
|
|
1087
|
+
const reason = this._isSuspendTriggeredByTimer ? "timer" : "appInitiated";
|
|
1088
|
+
this._isSuspendTriggeredByTimer = false;
|
|
1089
|
+
|
|
1090
|
+
if (window.cefQuery) {
|
|
1091
|
+
return new Promise((resolve, reject) => {
|
|
1092
|
+
const FCID = getFCID();
|
|
1093
|
+
const logger = sdkLogger.withFields({ FCID });
|
|
1094
|
+
const message = {
|
|
1095
|
+
type: "suspend",
|
|
1096
|
+
reason,
|
|
1097
|
+
fcid: FCID
|
|
1098
|
+
};
|
|
1099
|
+
const request = { target: "TC",
|
|
1100
|
+
waitForResponse: false,
|
|
1101
|
+
message: JSON.stringify(message) };
|
|
1102
|
+
|
|
1103
|
+
logger.log("moveToSuspended: sending suspend message");
|
|
1104
|
+
window.cefQuery({
|
|
1105
|
+
request: JSON.stringify(request),
|
|
1106
|
+
persistent: false,
|
|
1107
|
+
onSuccess: () => {
|
|
1108
|
+
logger.log("moveToSuspended request successfully sent");
|
|
1109
|
+
resolve(true);
|
|
1110
|
+
},
|
|
1111
|
+
onFailure: (code, msg) => {
|
|
1112
|
+
logger.error(`moveToSuspended failed: ${code} ${msg}`);
|
|
1113
|
+
reject(new SenzaError(code, msg));
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
sdkLogger.warn("moveToSuspended is not supported if NOT running e2e");
|
|
1119
|
+
return Promise.reject("moveToSuspended is not supported if NOT running e2e");
|
|
1120
|
+
}
|
|
1121
|
+
|
|
803
1122
|
|
|
804
1123
|
addEventListener(type, listener, options) {
|
|
805
1124
|
if (Lifecycle._waitForListenersEvents.includes(type)) {
|
|
@@ -100,10 +100,15 @@ class Lifecycle extends EventTarget {
|
|
|
100
100
|
* Configure lifecycle settings
|
|
101
101
|
* @param {Object} config - Configuration object
|
|
102
102
|
* @param {Object} [config.autoBackground] - Auto background settings
|
|
103
|
-
* @param {boolean} [config.autoBackground.enabled] - Enable/disable auto background
|
|
103
|
+
* @param {boolean} [config.autoBackground.enabled=true] - Enable/disable auto background
|
|
104
104
|
* @param {Object} [config.autoBackground.timeout] - Timeout settings
|
|
105
105
|
* @param {number|false} [config.autoBackground.timeout.playing=30] - Timeout in seconds when video is playing, false to disable
|
|
106
|
-
* @param {number|false} [config.autoBackground.timeout.idle=
|
|
106
|
+
* @param {number|false} [config.autoBackground.timeout.idle=30] - Timeout in seconds when in UI mode, false to disable
|
|
107
|
+
* @param {Object} [config.autoSuspend] - Auto suspend settings
|
|
108
|
+
* @param {boolean} [config.autoSuspend.enabled=false] - Enable/disable auto suspend
|
|
109
|
+
* @param {Object} [config.autoSuspend.timeout] - Timeout settings
|
|
110
|
+
* @param {number} [config.autoSuspend.timeout.playing=60] - Timeout in seconds when video is playing before moving to suspended state
|
|
111
|
+
* @param {number} [config.autoSuspend.timeout.idle=60] - Timeout in seconds when in background mode before moving to suspended state
|
|
107
112
|
*/
|
|
108
113
|
configure(config) {
|
|
109
114
|
noop("lifecycle.configure", config);
|
|
@@ -114,9 +119,12 @@ class Lifecycle extends EventTarget {
|
|
|
114
119
|
* @returns {Object} The current configuration object
|
|
115
120
|
* @example
|
|
116
121
|
* const config = lifecycle.getConfiguration();
|
|
117
|
-
* console.log(config.autoBackground.enabled); // true
|
|
122
|
+
* console.log(config.autoBackground.enabled); // true
|
|
118
123
|
* console.log(config.autoBackground.timeout.playing); // 30
|
|
119
|
-
* console.log(config.autoBackground.timeout.idle); //
|
|
124
|
+
* console.log(config.autoBackground.timeout.idle); // 30
|
|
125
|
+
* console.log(config.autoSuspend.enabled); // false
|
|
126
|
+
* console.log(config.autoSuspend.timeout.playing); // 60
|
|
127
|
+
* console.log(config.autoSuspend.timeout.idle); // 60
|
|
120
128
|
*/
|
|
121
129
|
getConfiguration() {
|
|
122
130
|
return {
|
|
@@ -126,6 +134,13 @@ class Lifecycle extends EventTarget {
|
|
|
126
134
|
playing: 0,
|
|
127
135
|
idle: 0
|
|
128
136
|
}
|
|
137
|
+
},
|
|
138
|
+
autoSuspend: {
|
|
139
|
+
enabled: false,
|
|
140
|
+
timeout: {
|
|
141
|
+
playing: 0,
|
|
142
|
+
idle: 0
|
|
143
|
+
}
|
|
129
144
|
}
|
|
130
145
|
};
|
|
131
146
|
}
|
|
@@ -279,6 +294,17 @@ class Lifecycle extends EventTarget {
|
|
|
279
294
|
return noop("lifecycle.disconnect");
|
|
280
295
|
}
|
|
281
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Use this api to move the application to suspended state.
|
|
299
|
+
* This method can only be called when the application is in BACKGROUND state.
|
|
300
|
+
* @return {Promise} Promise which is resolved when the suspend command has been successfully sent.
|
|
301
|
+
* Failure to process the suspend command will result in the promise being rejected.
|
|
302
|
+
* @alpha API has not yet been released
|
|
303
|
+
*/
|
|
304
|
+
moveToSuspended() {
|
|
305
|
+
return noop("lifecycle.moveToSuspended");
|
|
306
|
+
}
|
|
307
|
+
|
|
282
308
|
/**
|
|
283
309
|
* Add event listener for lifecycle events
|
|
284
310
|
* @param {string} type - The event type to listen for
|
package/src/interface/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "4.4.
|
|
1
|
+
export const version = "4.4.6";
|