You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2020/06/12 07:08:50 UTC

[openmeetings] branch master updated: [OPENMEETINGS-2365] NoSleep.js is added

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/master by this push:
     new 06f4030  [OPENMEETINGS-2365] NoSleep.js is added
06f4030 is described below

commit 06f40309b7f5a034c830ebdd9edc01dff81342b4
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Fri Jun 12 14:08:31 2020 +0700

    [OPENMEETINGS-2365] NoSleep.js is added
---
 .../db/dao/basic/ConfigurationDao.java             |   4 +-
 .../installation/ImportInitvalues.java             |  12 +-
 .../src/main/assembly/components/templates.xml     |   1 +
 .../openmeetings/util/OpenmeetingsVariables.java   |   6 +-
 openmeetings-web/pom.xml                           |   3 +
 .../org/apache/openmeetings/web/room/NoSleep.js    | 240 +++++++++++++++++++++
 .../org/apache/openmeetings/web/room/raw-room.js   |  15 +-
 pom.xml                                            |   3 +-
 8 files changed, 271 insertions(+), 13 deletions(-)

diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
index 575f59e..7be84df 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
@@ -592,8 +592,8 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 
 		setCspFontSrc(getString(CONFIG_CSP_FONT, DEFAULT_CSP_FONT));
 		setCspFrameSrc(getString(CONFIG_CSP_FRAME, SELF.getValue()));
-		setCspImageSrc(getString(CONFIG_CSP_IMAGE, DEFAULT_CSP_IMAGE));
-		setCspMediaSrc(getString(CONFIG_CSP_MEDIA, SELF.getValue()));
+		setCspImageSrc(getString(CONFIG_CSP_IMAGE, DEFAULT_CSP_DATA));
+		setCspMediaSrc(getString(CONFIG_CSP_MEDIA, DEFAULT_CSP_DATA));
 		setCspScriptSrc(getString(CONFIG_CSP_SCRIPT, STRICT_DYNAMIC.getValue()));
 		setCspStyleSrc(getString(CONFIG_CSP_STYLE, DEFAULT_CSP_STYLE));
 		if (Application.exists()) {
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
index b564ea4..dcef308 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
@@ -31,13 +31,13 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CALENDAR
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CAM_FPS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CHAT_SEND_ON_ENTER;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CRYPT;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_ENABLED;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_FONT;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_FRAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_IMAGE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_MEDIA;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_SCRIPT;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_STYLE;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_ENABLED;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_RSS_FEED1;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_RSS_FEED2;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_CHAT;
@@ -101,8 +101,8 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SMTP_TIM
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SMTP_TLS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SMTP_USER;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_APP_NAME;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_CSP_DATA;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_CSP_FONT;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_CSP_IMAGE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_CSP_STYLE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_MAX_UPLOAD_SIZE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_MINUTES_REMINDER_SEND;
@@ -374,10 +374,10 @@ public class ImportInitvalues {
 				+ cspMore, DEFAULT_CSP_FONT), VER_5_0_0);
 		addCfg(list, CONFIG_CSP_FRAME, SELF.getValue(), Configuration.Type.STRING, String.format("Value for 'frame-src' directive of 'Content-Security-Policy' header (default: %s)"
 				+ cspMore, SELF), VER_5_0_0);
-		addCfg(list, CONFIG_CSP_IMAGE, DEFAULT_CSP_IMAGE, Configuration.Type.STRING, String.format("Value for 'image-src' directive of 'Content-Security-Policy' header (default: %s)"
-				+ cspMore, DEFAULT_CSP_IMAGE), VER_5_0_0);
-		addCfg(list, CONFIG_CSP_MEDIA, SELF.getValue(), Configuration.Type.STRING, String.format("Value for 'media-src' directive of 'Content-Security-Policy' header (default: %s)"
-				+ cspMore, SELF), VER_5_0_0);
+		addCfg(list, CONFIG_CSP_IMAGE, DEFAULT_CSP_DATA, Configuration.Type.STRING, String.format("Value for 'image-src' directive of 'Content-Security-Policy' header (default: %s)"
+				+ cspMore, DEFAULT_CSP_DATA), VER_5_0_0);
+		addCfg(list, CONFIG_CSP_MEDIA, DEFAULT_CSP_DATA, Configuration.Type.STRING, String.format("Value for 'media-src' directive of 'Content-Security-Policy' header (default: %s)"
+				+ cspMore, DEFAULT_CSP_DATA), VER_5_0_0);
 		addCfg(list, CONFIG_CSP_SCRIPT, STRICT_DYNAMIC.getValue(), Configuration.Type.STRING, String.format("Value for 'script-src' directive of 'Content-Security-Policy' header (default: %s)"
 				+ cspMore, STRICT_DYNAMIC), VER_5_0_0);
 		addCfg(list, CONFIG_CSP_STYLE, DEFAULT_CSP_STYLE, Configuration.Type.STRING, String.format("Value for 'style-src' directive of 'Content-Security-Policy' header (default: %s)"
diff --git a/openmeetings-server/src/main/assembly/components/templates.xml b/openmeetings-server/src/main/assembly/components/templates.xml
index 5d3f7e6..68adfa8 100644
--- a/openmeetings-server/src/main/assembly/components/templates.xml
+++ b/openmeetings-server/src/main/assembly/components/templates.xml
@@ -39,6 +39,7 @@
 				<exclude>**/fileinput.css</exclude>
 				<exclude>**/adapter-latest.js</exclude>
 				<exclude>**/kurento-utils.js</exclude>
+				<exclude>**/NoSleep.js</exclude>
 				<exclude>**/network.js</exclude>
 			</excludes>
 		</fileSet>
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
index 91187d9..31467bf 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
@@ -119,7 +119,7 @@ public class OpenmeetingsVariables {
 	public static final String DEFAULT_SIP_CONTEXT = "rooms";
 	public static final String DEFAULT_CSP_FONT = "https://fonts.gstatic.com";
 	public static final String DEFAULT_CSP_STYLE = "https://fonts.googleapis.com/css";
-	public static final String DEFAULT_CSP_IMAGE = "data:";
+	public static final String DEFAULT_CSP_DATA = SELF.getValue() + ",data:";
 
 	private static String cryptClassName = null;
 	private static String wicketApplicationName = null;
@@ -154,8 +154,8 @@ public class OpenmeetingsVariables {
 	private static boolean myRoomsEnabled = true;
 	private static String cspFontSrc = DEFAULT_CSP_FONT;
 	private static String cspFrameSrc = SELF.getValue();
-	private static String cspImageSrc = DEFAULT_CSP_IMAGE;
-	private static String cspMediaSrc = SELF.getValue();
+	private static String cspImageSrc = DEFAULT_CSP_DATA;
+	private static String cspMediaSrc = DEFAULT_CSP_DATA;
 	private static String cspScriptSrc = STRICT_DYNAMIC.getValue();
 	private static String cspStyleSrc = DEFAULT_CSP_STYLE;
 	private static String smtpServer;
diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml
index 755d1f1..7268839 100644
--- a/openmeetings-web/pom.xml
+++ b/openmeetings-web/pom.xml
@@ -201,6 +201,7 @@
 							<charset>UTF-8</charset>
 							<jsSourceDir>../java/org/apache/openmeetings/web/room</jsSourceDir>
 							<jsSourceFiles>
+								<jsSourceFile>NoSleep.js</jsSourceFile>
 								<jsSourceFile>raw-video.js</jsSourceFile>
 								<jsSourceFile>raw-video-manager.js</jsSourceFile>
 								<jsSourceFile>raw-sharer.js</jsSourceFile>
@@ -281,6 +282,7 @@
 						**/fileinput.css,
 						**/adapter-latest.js,
 						**/kurento-utils.js,
+						**/NoSleep.js,
 						**/network.js
 					</packagingExcludes>
 					<warSourceExcludes>
@@ -292,6 +294,7 @@
 						**/fileinput.css,
 						**/adapter-latest.js,
 						**/kurento-utils.js,
+						**/NoSleep.js,
 						**/network.js
 					</warSourceExcludes>
 					<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NoSleep.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NoSleep.js
new file mode 100644
index 0000000..60e6761
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/NoSleep.js
@@ -0,0 +1,240 @@
+/*! NoSleep.js v0.11.0 - git.io/vfn01 - Rich Tibbett - MIT license */
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define([], factory);
+	else if(typeof exports === 'object')
+		exports["NoSleep"] = factory();
+	else
+		root["NoSleep"] = factory();
+})(window, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+/******/
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+/******/
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId]) {
+/******/ 			return installedModules[moduleId].exports;
+/******/ 		}
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			i: moduleId,
+/******/ 			l: false,
+/******/ 			exports: {}
+/******/ 		};
+/******/
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ 		// Flag the module as loaded
+/******/ 		module.l = true;
+/******/
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+/******/
+/******/
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+/******/
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+/******/
+/******/ 	// define getter function for harmony exports
+/******/ 	__webpack_require__.d = function(exports, name, getter) {
+/******/ 		if(!__webpack_require__.o(exports, name)) {
+/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ 		}
+/******/ 	};
+/******/
+/******/ 	// define __esModule on exports
+/******/ 	__webpack_require__.r = function(exports) {
+/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ 		}
+/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
+/******/ 	};
+/******/
+/******/ 	// create a fake namespace object
+/******/ 	// mode & 1: value is a module id, require it
+/******/ 	// mode & 2: merge all properties of value into the ns
+/******/ 	// mode & 4: return value when already ns object
+/******/ 	// mode & 8|1: behave like require
+/******/ 	__webpack_require__.t = function(value, mode) {
+/******/ 		if(mode & 1) value = __webpack_require__(value);
+/******/ 		if(mode & 8) return value;
+/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ 		var ns = Object.create(null);
+/******/ 		__webpack_require__.r(ns);
+/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ 		return ns;
+/******/ 	};
+/******/
+/******/ 	// getDefaultExport function for compatibility with non-harmony modules
+/******/ 	__webpack_require__.n = function(module) {
+/******/ 		var getter = module && module.__esModule ?
+/******/ 			function getDefault() { return module['default']; } :
+/******/ 			function getModuleExports() { return module; };
+/******/ 		__webpack_require__.d(getter, 'a', getter);
+/******/ 		return getter;
+/******/ 	};
+/******/
+/******/ 	// Object.prototype.hasOwnProperty.call
+/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+/******/
+/******/
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(__webpack_require__.s = 0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) [...]
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var _require = __webpack_require__(1),
+    webm = _require.webm,
+    mp4 = _require.mp4;
+
+// Detect iOS browsers < version 10
+
+
+var oldIOS = typeof navigator !== "undefined" && parseFloat(("" + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0, ""])[1]).replace("undefined", "3_2").replace("_", ".").replace("_", "")) < 10 && !window.MSStream;
+
+// Detect native Wake Lock API support
+var nativeWakeLock = "wakeLock" in navigator;
+
+var NoSleep = function () {
+  function NoSleep() {
+    var _this = this;
+
+    _classCallCheck(this, NoSleep);
+
+    if (nativeWakeLock) {
+      this._wakeLock = null;
+      var handleVisibilityChange = function handleVisibilityChange() {
+        if (_this._wakeLock !== null && document.visibilityState === "visible") {
+          _this.enable();
+        }
+      };
+      document.addEventListener("visibilitychange", handleVisibilityChange);
+      document.addEventListener("fullscreenchange", handleVisibilityChange);
+    } else if (oldIOS) {
+      this.noSleepTimer = null;
+    } else {
+      // Set up no sleep video element
+      this.noSleepVideo = document.createElement("video");
+
+      this.noSleepVideo.setAttribute("title", "No Sleep");
+      this.noSleepVideo.setAttribute("playsinline", "");
+
+      this._addSourceToVideo(this.noSleepVideo, "webm", webm);
+      this._addSourceToVideo(this.noSleepVideo, "mp4", mp4);
+
+      this.noSleepVideo.addEventListener("loadedmetadata", function () {
+        if (_this.noSleepVideo.duration <= 1) {
+          // webm source
+          _this.noSleepVideo.setAttribute("loop", "");
+        } else {
+          // mp4 source
+          _this.noSleepVideo.addEventListener("timeupdate", function () {
+            if (_this.noSleepVideo.currentTime > 0.5) {
+              _this.noSleepVideo.currentTime = Math.random();
+            }
+          });
+        }
+      });
+    }
+  }
+
+  _createClass(NoSleep, [{
+    key: "_addSourceToVideo",
+    value: function _addSourceToVideo(element, type, dataURI) {
+      var source = document.createElement("source");
+      source.src = dataURI;
+      source.type = "video/" + type;
+      element.appendChild(source);
+    }
+  }, {
+    key: "enable",
+    value: function enable() {
+      var _this2 = this;
+
+      if (nativeWakeLock) {
+        navigator.wakeLock.request("screen").then(function (wakeLock) {
+          _this2._wakeLock = wakeLock;
+          console.log("Wake Lock active.");
+          _this2._wakeLock.addEventListener("release", function () {
+            // ToDo: Potentially emit an event for the page to observe since
+            // Wake Lock releases happen when page visibility changes.
+            // (https://web.dev/wakelock/#wake-lock-lifecycle)
+            console.log("Wake Lock released.");
+          });
+        }).catch(function (err) {
+          console.error(err.name + ", " + err.message);
+        });
+      } else if (oldIOS) {
+        this.disable();
+        console.warn("\n        NoSleep enabled for older iOS devices. This can interrupt\n        active or long-running network requests from completing successfully.\n        See https://github.com/richtr/NoSleep.js/issues/15 for more details.\n      ");
+        this.noSleepTimer = window.setInterval(function () {
+          if (!document.hidden) {
+            window.location.href = window.location.href.split("#")[0];
+            window.setTimeout(window.stop, 0);
+          }
+        }, 15000);
+      } else {
+        this.noSleepVideo.play();
+      }
+    }
+  }, {
+    key: "disable",
+    value: function disable() {
+      if (nativeWakeLock) {
+        this._wakeLock.release();
+        this._wakeLock = null;
+      } else if (oldIOS) {
+        if (this.noSleepTimer) {
+          console.warn("\n          NoSleep now disabled for older iOS devices.\n        ");
+          window.clearInterval(this.noSleepTimer);
+          this.noSleepTimer = null;
+        }
+      } else {
+        this.noSleepVideo.pause();
+      }
+    }
+  }]);
+
+  return NoSleep;
+}();
+
+module.exports = NoSleep;
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+module.exports = {
+  webm: "data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA=",
+  mp4: "data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem [...]
+};
+
+/***/ })
+/******/ ]);
+});
\ No newline at end of file
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js
index 75572e3..6e5297f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js
@@ -1,7 +1,7 @@
 /* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
 var Room = (function() {
 	const self = {}, sbSide = Settings.isRtl ? 'right' : 'left';
-	let options, menuHeight, sb, dock, activities;
+	let options, menuHeight, sb, dock, activities, noSleep;
 
 	function _init(_options) {
 		options = _options;
@@ -158,6 +158,18 @@ var Room = (function() {
 		$(window).on('keydown.openmeetings', _preventKeydown);
 		$(window).on('keyup.openmeetings', _keyHandler);
 		$(document).click(_mouseHandler);
+		_addNoSleep();
+	}
+	function _addNoSleep() {
+		_removeNoSleep();
+		noSleep = new NoSleep();
+		noSleep.enable();
+	}
+	function _removeNoSleep() {
+		if (noSleep) {
+			noSleep.disable();
+			noSleep = null;
+		}
 	}
 	function _unload() {
 		$('body').removeClass('no-header');
@@ -179,6 +191,7 @@ var Room = (function() {
 		$(document).off('click', _mouseHandler);
 		sb = undefined;
 		Sharer.close();
+		_removeNoSleep();
 	}
 	function _showClipboard(txt) {
 		const dlg = $('#clipboard-dialog');
diff --git a/pom.xml b/pom.xml
index 22fd08d..a4dacdb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,7 +118,7 @@
 		<quartz.version>2.3.2</quartz.version>
 		<kurento.version>6.13.1</kurento.version>
 		<!--  Exclude all generated code  -->
-		<sonar.exclusions>file:**/generated-sources/**, file:**/jquery-ui.css, file:**/fabric.js, file:**/cssemoticons.js, file:**/adapter-latest.js, file:**/kurento-utils.js, file:**/fileinput*.js, file:**/MathJax.js, file:**/network.js</sonar.exclusions>
+		<sonar.exclusions>file:**/generated-sources/**, file:**/jquery-ui.css, file:**/fabric.js, file:**/cssemoticons.js, file:**/adapter-latest.js, file:**/kurento-utils.js, file:**/NoSleep.js, file:**/fileinput*.js, file:**/MathJax.js, file:**/network.js</sonar.exclusions>
 		<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
 		<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
 		<sonar.junit.reportPaths>target/surefire-reports</sonar.junit.reportPaths>
@@ -991,6 +991,7 @@
 									<pattern>Licensed under the MIT license</pattern>
 									<pattern>MIT/GPL2 Licensed</pattern>
 									<pattern>licensed under the MIT and GPL</pattern>
+									<pattern>MIT license</pattern>
 								</patterns>
 							</license>
 							<license implementation="org.apache.rat.analysis.license.SimplePatternBasedLicense">