Allow features to require optional permissions

Design doc:
https://docs.google.com/document/d/1OhL0Yh7SmWffXyjW_XVQOK95Fqh7gLltk1eEtnKN8Ds/edit

Fixed: twpowertools:86
Change-Id: Iccb22aac2b285307854b7a4c002e9702c24d57f2
diff --git a/src/background.js b/src/background.js
index a2bb071..7dc5faf 100644
--- a/src/background.js
+++ b/src/background.js
@@ -1,5 +1,6 @@
 // IMPORTANT: keep this file in sync with sw.js
-import {cleanUpOptions} from './common/optionsUtils.js';
+import {cleanUpOptPermissions} from './common/optionsPermissions.js';
+import {cleanUpOptions, disableItemsWithMissingPermissions} from './common/optionsUtils.js';
 import KillSwitchMechanism from './killSwitch/index.js';
 
 chrome.browserAction.onClicked.addListener(function() {
@@ -33,3 +34,34 @@
     killSwitchMechanism.updateKillSwitchStatus();
   }
 });
+
+// Clean up optional permissions and check that none are missing for enabled
+// features as soon as the extension starts and when the options change.
+cleanUpOptPermissions();
+
+chrome.storage.sync.onChanged.addListener(() => {
+  cleanUpOptPermissions();
+});
+
+chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
+  if (sender.id !== chrome.runtime.id)
+    return console.warn(
+        'An unknown sender (' + sender.id +
+            ') sent a message to the extension: ',
+        msg);
+
+  console.assert(msg.message);
+  switch (msg.message) {
+    case 'runDisableItemsWithMissingPermissions':
+      console.assert(
+          msg.options?.items && msg.options?.permissionChecksFeatures);
+      disableItemsWithMissingPermissions(
+          msg.options?.items, msg.options?.permissionChecksFeatures)
+          .then(items => sendResponse({status: 'resolved', items}))
+          .catch(error => sendResponse({status: 'rejected', error}));
+      break;
+
+    default:
+      console.warn('Unknown message "' + msg.message + '".');
+  }
+});