disable-autogain-control-extension
disable-autogain-control-extension copied to clipboard
Switch to Manifest v3 for Chrome
ChatGPT suggests the following v3 manifest ;-)
{
"name": "Disable Automatic Gain Control",
"version": "1.3",
"description": "Disables the automatic microphone gain control enabled by web applications like Google Meet and Hangouts.",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["installDisableAutogain.js"]
}
],
"web_accessible_resources": [
{
"resources": ["disableAutogain.js"],
"matches": ["<all_urls>"]
}
],
"action": {},
"permissions": [
"activeTab",
"contextMenus"
],
"host_permissions": [
"http://*/",
"https://*/"
]
}
And the following background.js changes:
// Show context menu that allows enabling/disabling on a per-domain basis.
chrome.action.onClicked.addListener((tab) => {
const { origin } = new URL(tab.url);
chrome.permissions.contains({
origins: [origin + "/*"],
}, (hasPermission) => {
if (hasPermission) {
chrome.permissions.remove({
origins: [origin + "/*"]
}, () => chrome.tabs.reload(tab.id));
} else {
chrome.permissions.request({
origins: [origin + "/*"]
}, () => chrome.tabs.reload(tab.id));
}
});
});
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
injectScriptIfNecessary(tab);
});
/**
* @param {chrome.tabs.Tab} tab
*/
function injectScriptIfNecessary(tab) {
if (tab.status !== "loading" || !tab.url) {
return;
}
try {
const { origin, protocol } = new URL(tab.url);
if (protocol !== "https:" && protocol !== "http:") {
return;
}
chrome.permissions.contains({
origins: [origin + "/*"]
}, (hasPermission) => {
if (hasPermission) {
// Note: ExecuteScript is not available in Manifest v3.
// You need to use content_scripts in the manifest instead of this line.
chrome.scripting.executeScript({
target: {tabId: tab.id, allFrames: true},
files: ["installDisableAutogain.js"]
});
}
chrome.action.setTitle({
title: hasPermission
? "Disable Automatic Gain Control"
: "Enable Automatic Gain Control",
tabId: tab.id,
});
chrome.action.setBadgeText({
text: hasPermission ? "On" : "",
tabId: tab.id,
});
});
} catch (e) {
console.error("Failed to inject script", e);
}
}
function showUsage() {
chrome.tabs.create({
url: chrome.runtime.getURL("usage.html")
});
}
function showUpgradeNotice() {
chrome.tabs.create({
url: chrome.runtime.getURL("upgradeFromV1.0.html")
});
}
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (typeof message === "object" && message["type"] === "enable-meet-hangouts") {
chrome.permissions.request({
origins: [
"https://meet.google.com/*",
"https://hangouts.google.com/*"
]
}, (granted) => {
sendResponse(granted);
});
return true;
}
});
chrome.contextMenus.create({
title: "Usage",
contexts: ["action"],
onclick: () => {
showUsage();
}
});
chrome.runtime.onInstalled.addListener(({ reason, previousVersion }) => {
if (reason === "update" && previousVersion === "1.0") {
showUpgradeNotice();
} else if (reason === "install") {
showUsage();
}
});
But I have absolutely no idea if it will work just like this -- just passing this along to see if it can help get this fixed smoothly...
@AlexWayfer @dot-i - I forked the repo and updated it for manifest-v3. It works as far as I've been using it, but i haven't done extensive functional testing.
Currently submitting it to the chrome webstore, but if you wanted to pull it down and load it directly, here's the repo. https://github.com/stratten/disable-autogain-control-extension
@AlexWayfer @dot-i - I forked the repo and updated it for manifest-v3. It works as far as I've been using it, but i haven't done extensive functional testing.
Currently submitting it to the chrome webstore, but if you wanted to pull it down and load it directly, here's the repo. https://github.com/stratten/disable-autogain-control-extension
@stratten thank you for your work on this! Your fork does indeed look like an usable alternative for d.a.g.c. I heard of your fork by a friend and I also plan to test it in chromium in the following days.
You told that you wanted to submit that one to the chrome web store. Do you already have new status updates on it how it keeps going or is it still waiting for the approval from Google?
@dtdan-03 - yeah, it was approved! And so far no one has reported any issues.
https://chromewebstore.google.com/detail/disable-automatic-gain-co/dfjdfadcciciboknnahlhgonamhfgmhp
@dot-i / @dtdan-03 - this is a quick breakdown of the core adjustments that were required:
- Migrated extension from Manifest V2 to V3
- Updated background script for MV3 service worker model
- Fixed permission handling and runtime errors
Key Updates:
- manifest.json → Manifest V3 migration
- Set MV3, moved to service worker, updated APIs, defined icons, corrected host permissions
{
"manifest_version": 3,
"background": { "service_worker": "background.js" },
"action": {},
"web_accessible_resources": [
{ "resources": ["disableAutogain.js"], "matches": ["<all_urls>"] }
],
"icons": {
"16": "images/icon16.png",
"32": "images/icon32.png",
"48": "images/icon48.png",
"128": "images/icon128.png"
},
"permissions": ["activeTab", "contextMenus", "scripting"],
"optional_host_permissions": ["http://*/", "https://*/"]
}
- background.js → MV2 APIs replaced with MV3 equivalents
- browserAction → action
- tabs.executeScript → scripting.executeScript
- extension.getURL → runtime.getURL
- Added protocol guard to avoid invalid schemes
- Moved context menu creation into onInstalled to avoid duplicate IDs
Action click: add protocol guard and dynamic per-origin permission toggle
chrome.action.onClicked.addListener(tab => {
const { origin, protocol } = new URL(tab.url);
if (protocol !== "https:" && protocol !== "http:") {
return; // prevents chrome-extension:// and other invalid schemes
}
chrome.permissions.contains({ origins: [origin + "/*"] }, hasPermission => {
if (hasPermission) {
chrome.permissions.remove({ origins: [origin + "/*"] }, () => chrome.tabs.reload(tab.id));
} else {
chrome.permissions.request({ origins: [origin + "/*"] }, () => chrome.tabs.reload(tab.id));
}
});
});
Inject the installer script when allowed
chrome.scripting.executeScript({
target: { tabId: tab.id, allFrames: true },
files: ["installDisableAutogain.js"]
});
Update title and badge
chrome.action.setTitle({ title: hasPermission ? "Disable Automatic Gain Control" : "Enable Automatic Gain Control", tabId: tab.id });
chrome.action.setBadgeText({ text: hasPermission ? "On" : "", tabId: tab.id });
runtime URL getters
chrome.runtime.getURL("usage.html");
chrome.runtime.getURL("upgradeFromV1.0.html");
Context menu: create once on install/enable, listen globally for clicks
chrome.runtime.onInstalled.addListener(({ reason, previousVersion }) => {
chrome.contextMenus.create({ title: "Usage", contexts: ["action"], id: "usage-menu" });
if (reason === "update" && previousVersion === "1.0") { showUpgradeNotice(); }
else if (reason === "install") { showUsage(); }
});
chrome.contextMenus.onClicked.addListener(info => {
if (info.menuItemId === "usage-menu") { showUsage(); }
});
Errors Resolved:
- Unsupported manifest version → Upgraded to MV3 (service_worker, action, web_accessible_resources changes)
- Permission 'http://*/' is unknown → Use optional_host_permissions (not optional_permissions)
- Invalid scheme for origin (chrome-extension://...) → Added protocol guard in action click handler and in injector
- You cannot remove required permissions → Made host permissions optional so they can be added/removed per-origin
- Cannot create item with duplicate id usage-menu → Create context menu in onInstalled only