diff --git a/src/engine/runtime.js b/src/engine/runtime.js index e1802a7bc3..ce6a0801ee 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -505,6 +505,12 @@ class Runtime extends EventEmitter { */ this.enforcePrivacy = true; + /** + * If true, an external communication method exists and enforcePrivacy is enabled. + * Do not update this directly. Must be changed via public functions that call Runtime.updatePrivacy(). + */ + this.privacyRestrictionsActive = false; + /** * Internal map of opaque identifiers to the callback to run that function. * @type {Map} @@ -3420,12 +3426,12 @@ class Runtime extends EventEmitter { } updatePrivacy () { - const enforceRestrictions = ( + this.privacyRestrictionsActive = ( this.enforcePrivacy && Object.values(this.externalCommunicationMethods).some(i => i) ); if (this.renderer && this.renderer.setPrivateSkinAccess) { - this.renderer.setPrivateSkinAccess(!enforceRestrictions); + this.renderer.setPrivateSkinAccess(!this.privacyRestrictionsActive); } } diff --git a/src/extensions/scratch3_video_sensing/index.js b/src/extensions/scratch3_video_sensing/index.js index 360b893ca3..3940043c06 100644 --- a/src/extensions/scratch3_video_sensing/index.js +++ b/src/extensions/scratch3_video_sensing/index.js @@ -531,6 +531,10 @@ class Scratch3VideoSensingBlocks { * @returns {number} the motion amount or direction of the stage or sprite */ videoOn (args, util) { + if (this.runtime.privacyRestrictionsActive) { + return -1; + } + this.detect.analyzeFrame(); let state = this.detect; @@ -554,6 +558,10 @@ class Scratch3VideoSensingBlocks { * reference */ whenMotionGreaterThan (args, util) { + if (this.runtime.privacyRestrictionsActive) { + return false; + } + this.detect.analyzeFrame(); const state = this._analyzeLocalMotion(util.target); return state.motionAmount > Number(args.REFERENCE); diff --git a/test/integration/tw_privacy.js b/test/integration/tw_privacy.js index fda382f711..0f2b1d760b 100644 --- a/test/integration/tw_privacy.js +++ b/test/integration/tw_privacy.js @@ -114,3 +114,17 @@ test('custom extensions', async t => { t.equal(vm.renderer.privateSkinAccess, false); t.end(); }); + +test('hasExternalCommunicationMethod', t => { + const vm = new VM(); + t.equal(vm.runtime.privacyRestrictionsActive, false); + vm.runtime.setExternalCommunicationMethod('cloudVariables', true); + t.equal(vm.runtime.privacyRestrictionsActive, true); + vm.runtime.setExternalCommunicationMethod('customExtensions', true); + t.equal(vm.runtime.privacyRestrictionsActive, true); + vm.runtime.setExternalCommunicationMethod('cloudVariables', false); + t.equal(vm.runtime.privacyRestrictionsActive, true); + vm.runtime.setExternalCommunicationMethod('customExtensions', false); + t.equal(vm.runtime.privacyRestrictionsActive, false); + t.end(); +});