senza-sdk 4.2.60 → 4.2.63-6c9a088.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 +16 -7
- package/src/api.js +182 -349
- package/src/{alarmManager.js → implementation/alarmManager.js} +15 -52
- package/src/implementation/api.js +367 -0
- package/src/{deviceManager.js → implementation/deviceManager.js} +7 -68
- package/src/{lifecycle.js → implementation/lifecycle.js} +5 -181
- package/src/{messageManager.js → implementation/messageManager.js} +6 -6
- package/src/{platformManager.js → implementation/platformManager.js} +5 -4
- package/src/{remotePlayer.js → implementation/remotePlayer.js} +11 -1
- package/src/{senzaShakaPlayer.js → implementation/senzaShakaPlayer.js} +220 -30
- package/src/{utils.js → implementation/utils.js} +15 -6
- package/src/interface/alarmManager.js +69 -0
- package/src/interface/api.js +8 -0
- package/src/interface/deviceManager.js +133 -0
- package/src/interface/lifecycle.js +278 -0
- package/src/interface/messageManager.js +46 -0
- package/src/interface/platformManager.js +35 -0
- package/src/interface/remotePlayer.js +441 -0
- package/src/interface/senzaShakaPlayer.js +171 -0
- package/src/interface/utils.js +45 -0
- /package/src/{SessionInfo.js → implementation/SessionInfo.js} +0 -0
- /package/src/{devHelper.js → implementation/devHelper.js} +0 -0
- /package/src/{eventListenersManager.js → implementation/eventListenersManager.js} +0 -0
- /package/src/{subtitlesUtils.js → implementation/subtitlesUtils.js} +0 -0
- /package/src/{devSequence.js → interface/devSequence.js} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { shaka } from "../interface/senzaShakaPlayer";
|
|
2
|
+
|
|
2
3
|
import { remotePlayer, lifecycle, getPlatformInfo } from "./api";
|
|
3
4
|
import { sdkLogger, iso6393to1 } from "./utils";
|
|
4
5
|
|
|
@@ -30,11 +31,6 @@ class SenzaError extends shaka.util.Error {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
// Copy the shaka module and replace the Player class with SenzaShakaPlayer
|
|
34
|
-
// if we don't Copy the shaka module, the Player class will be replaced for all the other modules that import shaka
|
|
35
|
-
const senzaShaka = { ...shaka };
|
|
36
|
-
|
|
37
|
-
|
|
38
34
|
/**
|
|
39
35
|
* SenzaShakaPlayer subclass of Shaka that handles both local and remote playback.
|
|
40
36
|
*
|
|
@@ -55,35 +51,92 @@ const senzaShaka = { ...shaka };
|
|
|
55
51
|
*/
|
|
56
52
|
|
|
57
53
|
export class SenzaShakaPlayer extends shaka.Player {
|
|
54
|
+
/** @private {SenzaShakaPlayer|null} Previous instance of the player */
|
|
58
55
|
static _prevInstance = null;
|
|
56
|
+
|
|
59
57
|
/**
|
|
60
58
|
* @private
|
|
61
59
|
* @type {Object.<string, string>}
|
|
62
|
-
* @description Map
|
|
60
|
+
* @description Map of audio track languages to their IDs
|
|
63
61
|
*/
|
|
64
62
|
_audioTracksMap = {};
|
|
65
63
|
|
|
66
64
|
/**
|
|
67
65
|
* @private
|
|
68
66
|
* @type {Object.<string, string>}
|
|
69
|
-
* @description Map
|
|
67
|
+
* @description Map of text track languages to their IDs
|
|
70
68
|
*/
|
|
71
69
|
_textTracksMap = {};
|
|
72
70
|
|
|
71
|
+
/**
|
|
72
|
+
* @private
|
|
73
|
+
* @type {number}
|
|
74
|
+
* @description Timeout in milliseconds to wait for playing event
|
|
75
|
+
* @default 3000
|
|
76
|
+
*/
|
|
77
|
+
_playingTimeout = 3000;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @private
|
|
81
|
+
* @type {number|null}
|
|
82
|
+
* @description Timestamp when play was called
|
|
83
|
+
*/
|
|
84
|
+
_playStartTime = null;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @private
|
|
88
|
+
* @type {boolean}
|
|
89
|
+
* @description Whether to stop remote player on error
|
|
90
|
+
* @default false
|
|
91
|
+
*/
|
|
92
|
+
_shouldStopRemotePlayerOnError = false;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @private
|
|
96
|
+
* @type {Function|null}
|
|
97
|
+
* @description Original play function from video element
|
|
98
|
+
*/
|
|
99
|
+
_originalPlay = null;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @private
|
|
103
|
+
* @type {Function|null}
|
|
104
|
+
* @description Resolve function for play promise
|
|
105
|
+
*/
|
|
106
|
+
_playPromiseResolve = null;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @private
|
|
110
|
+
* @type {Function|null}
|
|
111
|
+
* @description Reject function for play promise
|
|
112
|
+
*/
|
|
113
|
+
_playPromiseReject = null;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @private
|
|
117
|
+
* @type {number|null}
|
|
118
|
+
* @description Timer ID for play timeout
|
|
119
|
+
*/
|
|
120
|
+
_playTimeoutId = null;
|
|
121
|
+
|
|
73
122
|
/**
|
|
74
123
|
* @private
|
|
75
124
|
* @type {Object.<string, Function>}
|
|
76
|
-
* @description
|
|
125
|
+
* @description Event listeners for video element
|
|
77
126
|
*/
|
|
78
127
|
_videoEventListeners = {
|
|
79
128
|
"play": () => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
129
|
+
// keep old play behavior, in case playing timeout is defined as 0
|
|
130
|
+
if (this._playingTimeout === 0) {
|
|
131
|
+
this.remotePlayer.play()
|
|
132
|
+
.catch(error => {
|
|
133
|
+
sdkLogger.error("Failed to play remote player:", error);
|
|
134
|
+
this.handleSenzaError(error.code, error.message || "Unknown play error");
|
|
135
|
+
});
|
|
136
|
+
}
|
|
85
137
|
},
|
|
86
|
-
"pause": () => {
|
|
138
|
+
"pause" : () => {
|
|
139
|
+
this._resetPlayPromise();
|
|
87
140
|
this.remotePlayer.pause()
|
|
88
141
|
.catch(error => {
|
|
89
142
|
sdkLogger.error("Failed to pause remote player:", error);
|
|
@@ -97,7 +150,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
97
150
|
/**
|
|
98
151
|
* @private
|
|
99
152
|
* @type {Object.<string, Function>}
|
|
100
|
-
* @description
|
|
153
|
+
* @description Event listeners for remote player
|
|
101
154
|
*/
|
|
102
155
|
_remotePlayerEventListeners = {
|
|
103
156
|
"ended": () => {
|
|
@@ -109,7 +162,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
109
162
|
},
|
|
110
163
|
"error": (event) => {
|
|
111
164
|
sdkLogger.log("remotePlayer error:", event.detail.errorCode, event.detail.message);
|
|
112
|
-
// we need to move to foreground here for the auto background mode to work
|
|
113
165
|
lifecycle.moveToForeground();
|
|
114
166
|
this.handleSenzaError(event.detail.errorCode, event.detail.message);
|
|
115
167
|
},
|
|
@@ -129,7 +181,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
129
181
|
originatesFromRemotePlayer: true
|
|
130
182
|
};
|
|
131
183
|
|
|
132
|
-
const response = await this.getNetworkingEngine().request(
|
|
184
|
+
const response = await this.getNetworkingEngine().request(shaka.net.NetworkingEngine.RequestType.LICENSE, request).promise;
|
|
133
185
|
|
|
134
186
|
let responseBody = response.data;
|
|
135
187
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -166,17 +218,85 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
166
218
|
this._textTracksMap[lang] = track.id;
|
|
167
219
|
}
|
|
168
220
|
}
|
|
221
|
+
},
|
|
222
|
+
"playing": async () => {
|
|
223
|
+
sdkLogger.info("remotePlayer playing event received");
|
|
224
|
+
// If playing timeout was not expored, and the feature is set, handle the playing event
|
|
225
|
+
if (this._playingTimeout > 0 && this._playTimeoutId !== null) {
|
|
226
|
+
this._handlePlayingEvent();
|
|
227
|
+
}
|
|
169
228
|
}
|
|
170
229
|
};
|
|
171
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Clears the play timeout and resets the timer ID
|
|
233
|
+
* @private
|
|
234
|
+
* @description Cancels any pending play timeout and nullifies the timeout ID
|
|
235
|
+
*/
|
|
236
|
+
_clearPlayTimeout = () => {
|
|
237
|
+
if (this._playTimeoutId) {
|
|
238
|
+
sdkLogger.info("Clearing play timeout");
|
|
239
|
+
clearTimeout(this._playTimeoutId);
|
|
240
|
+
this._playTimeoutId = null;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* @private
|
|
245
|
+
* @description Handles the playing event from the remote player.
|
|
246
|
+
*/
|
|
247
|
+
_handlePlayingEvent = async () => {
|
|
248
|
+
|
|
249
|
+
this._clearPlayTimeout();
|
|
172
250
|
|
|
251
|
+
if (this.videoElement && this._originalPlay && this._playPromiseResolve) {
|
|
252
|
+
try {
|
|
253
|
+
const elapsedTime = Date.now() - this._playStartTime;
|
|
254
|
+
sdkLogger.info(`Time for playback start ${elapsedTime}ms`);
|
|
255
|
+
await this._originalPlay.call(this.videoElement);
|
|
256
|
+
sdkLogger.info("Video element play resolved successfully");
|
|
257
|
+
this._playPromiseResolve();
|
|
258
|
+
} catch (error) {
|
|
259
|
+
this._handlePlayPromiseError(error);
|
|
260
|
+
return;
|
|
261
|
+
} finally {
|
|
262
|
+
this._playPromiseResolve = null;
|
|
263
|
+
this._playPromiseReject = null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
};
|
|
173
267
|
/**
|
|
174
|
-
* Flag indicating whether the remote player should be stopped when an error occurs
|
|
175
268
|
* @private
|
|
176
|
-
* @
|
|
177
|
-
* @default false
|
|
269
|
+
* @description Resets the play promise state, clearing any existing resolve/reject functions and timeouts.
|
|
178
270
|
*/
|
|
179
|
-
|
|
271
|
+
_resetPlayPromise = () => {
|
|
272
|
+
if (this._playPromiseResolve) {
|
|
273
|
+
sdkLogger.info("Resolving play promise");
|
|
274
|
+
this._playPromiseResolve();
|
|
275
|
+
}
|
|
276
|
+
this._playPromiseResolve = null;
|
|
277
|
+
this._playPromiseReject = null;
|
|
278
|
+
this._clearPlayTimeout();
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Handles errors for play promises and remote player events.
|
|
284
|
+
* @private
|
|
285
|
+
* @param {Error} error - The error object.
|
|
286
|
+
*/
|
|
287
|
+
_handlePlayPromiseError(error) {
|
|
288
|
+
|
|
289
|
+
sdkLogger.error("Error while waiting for playing event:", error);
|
|
290
|
+
if (this._playPromiseReject) {
|
|
291
|
+
this._playPromiseReject(error);
|
|
292
|
+
this._playPromiseResolve = null;
|
|
293
|
+
this._playPromiseReject = null;
|
|
294
|
+
}
|
|
295
|
+
if (this._playTimeoutId) {
|
|
296
|
+
clearTimeout(this._playTimeoutId);
|
|
297
|
+
this._playTimeoutId = null;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
180
300
|
|
|
181
301
|
/**
|
|
182
302
|
* Creates an instance of SenzaShakaPlayer, which is a subclass of shaka.Player.
|
|
@@ -201,15 +321,62 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
201
321
|
|
|
202
322
|
this.remotePlayer = remotePlayer;
|
|
203
323
|
this._addRemotePlayerEventListeners();
|
|
324
|
+
SenzaShakaPlayer._prevInstance = this;
|
|
325
|
+
const playTimeout = getPlatformInfo()?.sessionInfo?.settings?.["ui-streamer"]?.playingEventTimeout;
|
|
326
|
+
this._playingTimeout = (playTimeout >= 0) ? playTimeout*1000 : this._playingTimeout;
|
|
327
|
+
|
|
204
328
|
// if video element is provided, add the listeres here. In this case ,there is no need to call attach.
|
|
205
329
|
if (videoElement) {
|
|
206
|
-
this.videoElement
|
|
207
|
-
this._attachVideoElementToRemotePlayer();
|
|
330
|
+
this._attach(videoElement);
|
|
208
331
|
sdkLogger.warn("SenzaShakaPlayer constructor Adding videoElement in the constructor is going to be deprecated in the future. Please use attach method instead.");
|
|
209
332
|
}
|
|
210
|
-
SenzaShakaPlayer._prevInstance = this;
|
|
211
333
|
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
_attach(videoElement) {
|
|
337
|
+
this.videoElement = videoElement;
|
|
338
|
+
|
|
339
|
+
// Store original play and replace with our implementation.
|
|
340
|
+
if (this._playingTimeout > 0) {
|
|
341
|
+
this._originalPlay = this.videoElement.play;
|
|
342
|
+
this.videoElement.play = async () => {
|
|
343
|
+
if (this._playPromiseResolve || this._playPromiseReject) {
|
|
344
|
+
sdkLogger.warn("play() was called while a play promise is already pending. Ignoring play call.");
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Clear any existing timeout
|
|
349
|
+
if (this._playTimeoutId) {
|
|
350
|
+
clearTimeout(this._playTimeoutId);
|
|
351
|
+
}
|
|
352
|
+
// Store the timestamp of the play call
|
|
353
|
+
this._playStartTime = Date.now();
|
|
354
|
+
|
|
355
|
+
const returnPromise = new Promise((resolve, reject) => {
|
|
356
|
+
this._playPromiseResolve = resolve;
|
|
357
|
+
this._playPromiseReject = reject;
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
});
|
|
361
|
+
// Set timeout to reject if playing event doesn't arrive
|
|
362
|
+
this._playTimeoutId = setTimeout(() => {
|
|
363
|
+
sdkLogger.error("Playing event timeout reached");
|
|
364
|
+
// when timeout reached start the local playback anyway
|
|
365
|
+
this._handlePlayingEvent();
|
|
366
|
+
}, this._playingTimeout);
|
|
367
|
+
await this.remotePlayer.play()
|
|
368
|
+
.catch(error => {
|
|
369
|
+
sdkLogger.error("Failed to play remote player:", error);
|
|
370
|
+
this.handleSenzaError(error.code, error.message || "Unknown play error");
|
|
371
|
+
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// Create a new promise that will resolve when the real play succeeds
|
|
375
|
+
return returnPromise;
|
|
376
|
+
};
|
|
377
|
+
};
|
|
212
378
|
|
|
379
|
+
this._attachVideoElementToRemotePlayer();
|
|
213
380
|
}
|
|
214
381
|
|
|
215
382
|
/**
|
|
@@ -220,8 +387,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
220
387
|
*/
|
|
221
388
|
async attach(videoElement, initializeMediaSource = true) {
|
|
222
389
|
await super.attach(videoElement, initializeMediaSource);
|
|
223
|
-
this.videoElement
|
|
224
|
-
this._attachVideoElementToRemotePlayer();
|
|
390
|
+
this._attach(videoElement);
|
|
225
391
|
}
|
|
226
392
|
|
|
227
393
|
/**
|
|
@@ -235,6 +401,17 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
235
401
|
* @export
|
|
236
402
|
*/
|
|
237
403
|
async detach(keepAdManager = false) {
|
|
404
|
+
// Clear any pending timeout
|
|
405
|
+
this._resetPlayPromise();
|
|
406
|
+
|
|
407
|
+
if (this.videoElement && this._originalPlay) {
|
|
408
|
+
// Clear any pending play promise
|
|
409
|
+
this._playPromiseResolve = null;
|
|
410
|
+
this._playPromiseReject = null;
|
|
411
|
+
// Restore original play function before detaching
|
|
412
|
+
this.videoElement.play = this._originalPlay;
|
|
413
|
+
this._originalPlay = null;
|
|
414
|
+
}
|
|
238
415
|
|
|
239
416
|
await super.detach(keepAdManager);
|
|
240
417
|
this._audioTracksMap = {};
|
|
@@ -265,6 +442,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
265
442
|
// Call the remote player's unload method
|
|
266
443
|
try {
|
|
267
444
|
await lifecycle.moveToForeground();
|
|
445
|
+
this._clearPlayTimeout();
|
|
268
446
|
await remotePlayer.unload();
|
|
269
447
|
} catch (error) {
|
|
270
448
|
sdkLogger.error("Failed to unload remote player:", error);
|
|
@@ -391,7 +569,8 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
391
569
|
sdkLogger.error("Error while trying to stop video element playback:", stopError);
|
|
392
570
|
}
|
|
393
571
|
}
|
|
394
|
-
|
|
572
|
+
// Handle error while waiting for play event
|
|
573
|
+
this._handlePlayPromiseError(error);
|
|
395
574
|
this.dispatchEvent(new shaka.util.FakeEvent("error", errorMap));
|
|
396
575
|
}
|
|
397
576
|
|
|
@@ -487,6 +666,17 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
487
666
|
return super.destroy();
|
|
488
667
|
}
|
|
489
668
|
|
|
669
|
+
/**
|
|
670
|
+
* A temporary override for older versions of Shaka.
|
|
671
|
+
* Senza doesn't support out-of-band subtitles
|
|
672
|
+
*/
|
|
673
|
+
addTextTrack(uri, language, kind, mimeType, codec, label, forced = false) {
|
|
674
|
+
sdkLogger.warn("addTextTrack is deprecated, please use addTextTrackAsync");
|
|
675
|
+
super.addTextTrackAsync(uri, language, kind, mimeType, codec, label, forced).then(subs => {
|
|
676
|
+
sdkLogger.warn("addTextTrackAsync Done" + subs);
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
|
|
490
680
|
/**
|
|
491
681
|
* Override the configure method to add custom configuration handling
|
|
492
682
|
* Supports the following additional configuration options:
|
|
@@ -610,5 +800,5 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
610
800
|
|
|
611
801
|
}
|
|
612
802
|
|
|
613
|
-
|
|
614
|
-
export {
|
|
803
|
+
shaka.Player = SenzaShakaPlayer;
|
|
804
|
+
export { shaka };
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { getPlatformInfo } from "./api";
|
|
2
|
-
import pack from "../package.json";
|
|
3
2
|
import { sessionInfo } from "./SessionInfo";
|
|
4
|
-
const { version } = pack;
|
|
5
3
|
|
|
6
4
|
const REST_RESPONSE_TIMEOUT_SECONDS = 5;
|
|
7
5
|
|
|
6
|
+
export function getVersion() {
|
|
7
|
+
return typeof IMPLEMENTATION_VERSION !== "undefined"
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
? IMPLEMENTATION_VERSION
|
|
10
|
+
: "unknown";
|
|
11
|
+
};
|
|
12
|
+
|
|
8
13
|
export function getFCID() {
|
|
9
14
|
return Math.round(Math.random() * 100000) + "-" + getPlatformInfo().sessionInfo?.connectionId;
|
|
10
15
|
}
|
|
@@ -42,7 +47,7 @@ class SdkLogger {
|
|
|
42
47
|
console.info(`[hs-sdk] [metrics] ${JSON.stringify(metricObj)}`);
|
|
43
48
|
}
|
|
44
49
|
withFields(logFields) {
|
|
45
|
-
return new SdkLogger({...this.logFields, ...logFields});
|
|
50
|
+
return new SdkLogger({ ...this.logFields, ...logFields });
|
|
46
51
|
}
|
|
47
52
|
formatLogString(data) {
|
|
48
53
|
let logString = "[hs-sdk] " + data.join(" ");
|
|
@@ -51,9 +56,13 @@ class SdkLogger {
|
|
|
51
56
|
}
|
|
52
57
|
return logString;
|
|
53
58
|
}
|
|
59
|
+
addfields(fields) {
|
|
60
|
+
this.logFields = { ...this.logFields, ...fields };
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
54
63
|
}
|
|
55
64
|
|
|
56
|
-
export const sdkLogger = new SdkLogger({sdkVersion:
|
|
65
|
+
export const sdkLogger = new SdkLogger({ sdkVersion: getVersion(), url: window?.location?.href ?? "" });
|
|
57
66
|
|
|
58
67
|
export async function getRestResponse(messageName) {
|
|
59
68
|
|
|
@@ -64,14 +73,14 @@ export async function getRestResponse(messageName) {
|
|
|
64
73
|
|
|
65
74
|
return new Promise((resolve, reject) => {
|
|
66
75
|
const FCID = getFCID();
|
|
67
|
-
const logger = sdkLogger.withFields({FCID});
|
|
76
|
+
const logger = sdkLogger.withFields({ FCID });
|
|
68
77
|
const message = {
|
|
69
78
|
type: "restRequest",
|
|
70
79
|
name: messageName,
|
|
71
80
|
method: "GET",
|
|
72
81
|
fcid: FCID
|
|
73
82
|
};
|
|
74
|
-
const request = {target: "TC", waitForResponse: true, message: JSON.stringify(message)};
|
|
83
|
+
const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
|
|
75
84
|
let timeoutHandler = 0;
|
|
76
85
|
const queryId = window.cefQuery({
|
|
77
86
|
request: JSON.stringify(request),
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { noop } from "./utils";
|
|
2
|
+
/**
|
|
3
|
+
* @class AlarmManager
|
|
4
|
+
* AlarmManager is a singleton class that manages the alarms in the application. It fires events whose types are the names of the alarms.
|
|
5
|
+
* @fires MyAlarm
|
|
6
|
+
*/
|
|
7
|
+
export class AlarmManager extends EventTarget {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* alarm event
|
|
11
|
+
*
|
|
12
|
+
* @event AlarmManager#MyAlarm
|
|
13
|
+
* @description Fired when time of 'MyAlarm' arrives. If this alarm triggers the application load and the application doesn't call
|
|
14
|
+
* lifecycle.moveToForeground() in the alarm callback (i.e. the application remains in the background after the callback is completed),
|
|
15
|
+
* the application will be unloaded.
|
|
16
|
+
* NOTE: If you perform async operations in the callback (without moving to foreground), you must wait for the async
|
|
17
|
+
* operation to finish before returning from the callback, otherwise the application will be unloaded before the async operation is finished.<br>
|
|
18
|
+
* @example
|
|
19
|
+
* alarmManager.addEventListener("MyAlarm", async (e) => {
|
|
20
|
+
* console.log("alarm MyAlarm arrived with data", e.detail);
|
|
21
|
+
* await fetch("http://www.example.com");
|
|
22
|
+
* });
|
|
23
|
+
* alarmManager.addAlarm("MyAlarm", Date.now() + 60*60*1000, "MyData");
|
|
24
|
+
*/
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
addEventListener(type, callback) {
|
|
30
|
+
noop("AlarmManager.addEventListener", type, callback);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
removeEventListener(type, callback) {
|
|
34
|
+
noop("AlarmManager.removeEventListener", type, callback);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Set alarm to be fired at the specified time, event when ui is released
|
|
38
|
+
* @param {string} alarmName unique name for the alarm
|
|
39
|
+
* @param {number} alarmTime target time for the alarm to be fired, represented by the number of milliseconds elapsed since the epoch
|
|
40
|
+
* @param {string} [data] data to be passed back when the alarm is fired
|
|
41
|
+
* */
|
|
42
|
+
addAlarm(alarmName, alarmTime, data = "", toleranceBefore = 0, toleranceAfter = 0) {
|
|
43
|
+
noop("AlarmManager.addAlarm", alarmName, alarmTime, data, toleranceBefore, toleranceAfter);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Delete the specified alarm
|
|
47
|
+
* @param {string} alarmName name of alarm to be deleted
|
|
48
|
+
*
|
|
49
|
+
* */
|
|
50
|
+
deleteAlarm(alarmName) {
|
|
51
|
+
noop("AlarmManager.deleteAlarm", alarmName);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Delete all alarms
|
|
55
|
+
*
|
|
56
|
+
* */
|
|
57
|
+
deleteAllAlarms() {
|
|
58
|
+
noop("AlarmManager.deleteAllAlarms");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Async function that asks for all active alarms
|
|
62
|
+
* @returns {Promise} when resolved, returns an array of objects containing alarmName and alarmTime fields
|
|
63
|
+
* @throws {string} error string in case of an error
|
|
64
|
+
*
|
|
65
|
+
* */
|
|
66
|
+
getActiveAlarms() {
|
|
67
|
+
return noop("AlarmManager.getActiveAlarms");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Lifecycle } from "./lifecycle.js";
|
|
2
|
+
export { DeviceManager } from "./deviceManager.js";
|
|
3
|
+
export { PlatformManager } from "./platformManager.js";
|
|
4
|
+
export { AlarmManager } from "./alarmManager.js";
|
|
5
|
+
export { MessageManager } from "./messageManager.js";
|
|
6
|
+
export { RemotePlayer } from "./remotePlayer.js";
|
|
7
|
+
export { SenzaShakaPlayer as ShakaPlayer, shaka } from "./senzaShakaPlayer.js";
|
|
8
|
+
export { showSequence, initSequence } from "./devSequence.js";
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { sdkLogger, noop } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
const wifiInfo = {};
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class DeviceManager
|
|
7
|
+
* DeviceManager is a singleton class that manages the device
|
|
8
|
+
*/
|
|
9
|
+
export class DeviceManager extends EventTarget {
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
wifiInfo.level = 0;
|
|
14
|
+
wifiInfo.quality = 0;
|
|
15
|
+
wifiInfo.ssid = "unknown";
|
|
16
|
+
wifiInfo.bssid = "unknown";
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Instead, call deviceManager.getWifiInfo() periodically
|
|
19
|
+
* @event DeviceManager#wifiInfoUpdated
|
|
20
|
+
* @example
|
|
21
|
+
* deviceManager.addEventListener("wifiInfoUpdated", () => {
|
|
22
|
+
* console.info("Wifi info has been updated to", deviceManager.wifiInfo);
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @property {object} DeviceInfo
|
|
30
|
+
* @property {string} DeviceInfo.deviceId
|
|
31
|
+
* @property {string} DeviceInfo.modelNumber
|
|
32
|
+
* @property {string} DeviceInfo.connectionId
|
|
33
|
+
* @property {string} DeviceInfo.community
|
|
34
|
+
* @property {string} DeviceInfo.tenant
|
|
35
|
+
* @property {string} DeviceInfo.clientIp
|
|
36
|
+
* @property {string} DeviceInfo.countryCode A 2-letter code as defined in ISO_3166-1
|
|
37
|
+
* @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.
|
|
38
|
+
*/
|
|
39
|
+
get deviceInfo() {
|
|
40
|
+
sdkLogger.log("getDeviceInfo running locally, returning dummy info");
|
|
41
|
+
return {
|
|
42
|
+
deviceId: "123456789",
|
|
43
|
+
modelNumber: "ABC",
|
|
44
|
+
connectionId: "dummy",
|
|
45
|
+
community: "LocalDev",
|
|
46
|
+
tenant: "XXXXXX",
|
|
47
|
+
clientIp: "0.0.0.0",
|
|
48
|
+
countryCode: "XX",
|
|
49
|
+
connectionType: "simulator"
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @deprecated use deviceManager.getWifiInfo() instead
|
|
56
|
+
* @property {object} WifiInfo
|
|
57
|
+
* @property {number} WifiInfo.level
|
|
58
|
+
* @property {number} WifiInfo.quality
|
|
59
|
+
* @property {string} WifiInfo.ssid
|
|
60
|
+
* @property {string} WifiInfo.bssid
|
|
61
|
+
*/
|
|
62
|
+
get wifiInfo() {
|
|
63
|
+
return wifiInfo;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Reboot the device
|
|
68
|
+
* @return {Promise} Promise which is resolved when the reboot command has been successfully processed.
|
|
69
|
+
* Failure to process the reboot command will result in the promise being rejected.
|
|
70
|
+
*/
|
|
71
|
+
reboot() {
|
|
72
|
+
return noop("DeviceManager.reboot");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Delete current wifi configuration and forget network
|
|
77
|
+
* @return {Promise} Promise which is resolved when the clearWifi command has been successfully processed.
|
|
78
|
+
* Failure to process the clearWifi command will result in the promise being rejected.
|
|
79
|
+
*/
|
|
80
|
+
clearWifi() {
|
|
81
|
+
return noop("DeviceManager.clearWifi");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Send raw data directly to a customer's device via the USB serial connection of a Senza device.
|
|
86
|
+
* This function is specifically designed for customers who have their devices connected to a Senza device.
|
|
87
|
+
* Using this API, these customers can transmit messages or data directly to their connected devices.
|
|
88
|
+
* The transmission occurs through the Senza device's USB serial interface, facilitating direct communication
|
|
89
|
+
* between the customer's web application and their device.
|
|
90
|
+
* @param {String} data raw data to be passed to the device
|
|
91
|
+
* @return {Promise} Promise which is resolved when the command has been successfully processed.
|
|
92
|
+
* Failure to process the command will result in the promise being rejected.
|
|
93
|
+
*/
|
|
94
|
+
sendDataToDevice(data) {
|
|
95
|
+
return noop("DeviceManager.sendDataToDevice", data);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Perform device factory reset.
|
|
100
|
+
* @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.
|
|
101
|
+
* @return {Promise} Promise which is resolved when factoryReset has been successfully performed
|
|
102
|
+
* Failure to factoryReset for any reason, result in the promise being rejected.
|
|
103
|
+
*/
|
|
104
|
+
async factoryReset(reboot = true) {
|
|
105
|
+
return noop("DeviceManager.factoryReset", reboot);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @typedef {Object} WiFiInfo
|
|
110
|
+
* @property {string} ssid the name of the Wi-Fi network that the device is connected to
|
|
111
|
+
* @property {string} bssid the unique identifier of the Wi-Fi access point
|
|
112
|
+
* @property {string} standard the Wi-Fi standard in use, such as 802.11a/b/g/n/ac/ax
|
|
113
|
+
* @property {string} security the type of security protocol used by the Wi-Fi network, such as WEP, WPA, WPA2, or WPA3
|
|
114
|
+
* @property {string} device-mac the MAC address of the device
|
|
115
|
+
* @property {string} device-ip4 the IPv4 address assigned to the device on the Wi-Fi network
|
|
116
|
+
* @property {string} dhcp-server the IP address of the DHCP server that assigned the device's network configuration
|
|
117
|
+
* @property {string[]} dns-server array of IP addresses of the DNS servers the device uses to resolve domain names
|
|
118
|
+
* @property {number} channel the number of the Wi-Fi channel currently being used
|
|
119
|
+
* @property {number} width width of the Wi-Fi channel in megahertz, e.g. 20MHz or 40 MHz channel
|
|
120
|
+
* @property {number} level a measure of the received signal strength, in the range 0 to 100 (the higher, the better). The level value is 100+RSSI (RSSI is the signal strength, measured in decibels)
|
|
121
|
+
* @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.
|
|
122
|
+
* */
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get Wi-Fi info - access point data and status (the status is cached for 5 seconds)
|
|
126
|
+
* @returns {WiFiInfo} An object containing the Wi-Fi info
|
|
127
|
+
* @alpha API has not yet been released
|
|
128
|
+
* */
|
|
129
|
+
// This api is part of epic HSDEV-4185
|
|
130
|
+
async getWifiInfo() {
|
|
131
|
+
return Promise.resolve({});
|
|
132
|
+
}
|
|
133
|
+
}
|