blob: 4244e93411aca165d71ffc66a792e184ed787822 [file] [log] [blame]
Adrià Vilanova Martínez54fbad12022-01-04 03:39:04 +01001// #!if browser_target == 'chromium_mv3'
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +02002import XMLHttpRequest from 'sw-xhr';
Adrià Vilanova Martínez54fbad12022-01-04 03:39:04 +01003// #!endif
avm99963bbc88c62020-12-25 03:44:41 +01004
Adrià Vilanova Martínez54fbad12022-01-04 03:39:04 +01005import actionApi from './common/actionApi.js';
Adrià Vilanova Martínez5120dbb2022-01-04 03:21:17 +01006import {cleanUpOptPermissions} from './common/optionsPermissions.js';
7import {cleanUpOptions, disableItemsWithMissingPermissions} from './common/optionsUtils.js';
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +02008import KillSwitchMechanism from './killSwitch/index.js';
Adrià Vilanova Martíneza4dd5fd2022-01-05 04:23:44 +01009import {handleBgOptionChange, handleBgOptionsOnStart} from './options/bgHandler.js';
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +020010
Adrià Vilanova Martínez54fbad12022-01-04 03:39:04 +010011// #!if browser_target == 'chromium_mv3'
12// XMLHttpRequest is not present in service workers (MV3) and is required by the
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +020013// grpc-web package. Importing a shim to work around this.
14// https://github.com/grpc/grpc-web/issues/1134
15self.XMLHttpRequest = XMLHttpRequest;
Adrià Vilanova Martínez54fbad12022-01-04 03:39:04 +010016// #!endif
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +020017
Adrià Vilanova Martínez258b4aa2022-01-15 22:01:01 +010018// Returns whether the script is being ran when the extension starts up. It does
19// so on a best-effort-basis.
20function isExtensionStartup() {
21 // If chrome.storage.session isn't implemented in this version of Chrome, we
22 // don't know whether it's the extension startup.
23 if (!chrome.storage.session) return Promise.resolve(true);
24
25 return new Promise((resolve, reject) => {
26 return chrome.storage.session.get('hasAlreadyStarted', v => {
27 resolve(v.hasAlreadyStarted !== true);
28 });
29 });
30}
31
32// Sets that the extension has already started up
33function setHasAlreadyStarted() {
34 if (!chrome.storage.session) return;
35 chrome.storage.session.set({
36 hasAlreadyStarted: true,
37 });
38}
39
Adrià Vilanova Martínez54fbad12022-01-04 03:39:04 +010040actionApi.onClicked.addListener(() => {
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +020041 chrome.runtime.openOptionsPage();
42});
43
44const killSwitchMechanism = new KillSwitchMechanism();
45
Adrià Vilanova Martínez258b4aa2022-01-15 22:01:01 +010046chrome.alarms.get('updateKillSwitchStatus', alarm => {
47 if (!alarm)
48 chrome.alarms.create('updateKillSwitchStatus', {
49 periodInMinutes: PRODUCTION ? 30 : 1,
50 });
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +020051});
52
53chrome.alarms.onAlarm.addListener(alarm => {
54 if (alarm.name === 'updateKillSwitchStatus')
55 killSwitchMechanism.updateKillSwitchStatus();
56});
57
58// When the profile is first started, update the kill switch status.
59chrome.runtime.onStartup.addListener(() => {
60 killSwitchMechanism.updateKillSwitchStatus();
61});
62
63// When the extension is first installed or gets updated, set new options to
64// their default value and update the kill switch status.
avm99963bbc88c62020-12-25 03:44:41 +010065chrome.runtime.onInstalled.addListener(details => {
66 if (details.reason == 'install' || details.reason == 'update') {
67 chrome.storage.sync.get(null, options => {
avm99963bf8eece2021-04-22 00:27:03 +020068 cleanUpOptions(options, false);
avm99963bbc88c62020-12-25 03:44:41 +010069 });
avm99963bbc88c62020-12-25 03:44:41 +010070
Adrià Vilanova Martínez413cb442021-09-06 00:30:45 +020071 killSwitchMechanism.updateKillSwitchStatus();
72 }
avm99963bbc88c62020-12-25 03:44:41 +010073});
Adrià Vilanova Martínez5120dbb2022-01-04 03:21:17 +010074
75// Clean up optional permissions and check that none are missing for enabled
Adrià Vilanova Martíneza4dd5fd2022-01-05 04:23:44 +010076// features, and also handle background option changes as soon as the extension
77// starts and when the options change.
Adrià Vilanova Martínezbc4d6a32022-02-12 16:47:34 +010078chrome.storage.onChanged.addListener((changes, areaName) => {
79 if (areaName !== 'sync') return;
Adrià Vilanova Martínez5120dbb2022-01-04 03:21:17 +010080 cleanUpOptPermissions();
Adrià Vilanova Martíneza4dd5fd2022-01-05 04:23:44 +010081
82 for (let [key, {oldValue, newValue}] of Object.entries(changes)) {
83 handleBgOptionChange(key);
84 }
Adrià Vilanova Martínez5120dbb2022-01-04 03:21:17 +010085});
86
87chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
88 if (sender.id !== chrome.runtime.id)
89 return console.warn(
90 'An unknown sender (' + sender.id +
91 ') sent a message to the extension: ',
92 msg);
93
94 console.assert(msg.message);
95 switch (msg.message) {
96 case 'runDisableItemsWithMissingPermissions':
97 console.assert(
98 msg.options?.items && msg.options?.permissionChecksFeatures);
99 disableItemsWithMissingPermissions(
100 msg.options?.items, msg.options?.permissionChecksFeatures)
101 .then(items => sendResponse({status: 'resolved', items}))
102 .catch(error => sendResponse({status: 'rejected', error}));
103 break;
104
105 default:
106 console.warn('Unknown message "' + msg.message + '".');
107 }
108});
Adrià Vilanova Martínez258b4aa2022-01-15 22:01:01 +0100109
110// This should only run once when the extension starts up.
111isExtensionStartup().then(isStartup => {
112 if (isStartup) {
113 cleanUpOptPermissions();
114 handleBgOptionsOnStart();
115 setHasAlreadyStarted();
116 }
117});