blob: a0864d8c8a5a9be07a513adb7d1a3d03e2a2f955 [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íneza4dd5fd2022-01-05 04:23:44 +010078chrome.storage.sync.onChanged.addListener(changes => {
Adrià Vilanova Martínez5120dbb2022-01-04 03:21:17 +010079 cleanUpOptPermissions();
Adrià Vilanova Martíneza4dd5fd2022-01-05 04:23:44 +010080
81 for (let [key, {oldValue, newValue}] of Object.entries(changes)) {
82 handleBgOptionChange(key);
83 }
Adrià Vilanova Martínez5120dbb2022-01-04 03:21:17 +010084});
85
86chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
87 if (sender.id !== chrome.runtime.id)
88 return console.warn(
89 'An unknown sender (' + sender.id +
90 ') sent a message to the extension: ',
91 msg);
92
93 console.assert(msg.message);
94 switch (msg.message) {
95 case 'runDisableItemsWithMissingPermissions':
96 console.assert(
97 msg.options?.items && msg.options?.permissionChecksFeatures);
98 disableItemsWithMissingPermissions(
99 msg.options?.items, msg.options?.permissionChecksFeatures)
100 .then(items => sendResponse({status: 'resolved', items}))
101 .catch(error => sendResponse({status: 'rejected', error}));
102 break;
103
104 default:
105 console.warn('Unknown message "' + msg.message + '".');
106 }
107});
Adrià Vilanova Martínez258b4aa2022-01-15 22:01:01 +0100108
109// This should only run once when the extension starts up.
110isExtensionStartup().then(isStartup => {
111 if (isStartup) {
112 cleanUpOptPermissions();
113 handleBgOptionsOnStart();
114 setHasAlreadyStarted();
115 }
116});