onInstall tabs.create not working when enabling privacy mode (Firefox Android - bug)

I have an extension that is both available for Firefox desktop and Firefox Android. I want to open a specific website to register users when the extension is installed.

However, this does not work in Firefox Android. When the add dialog shows and you click “add” the register website opens. However, when the additional dialog (only on Android) “allowing the extension in the privacy browser” is enabled then the register website is automatically closed. If you don’t allow the privacy browser, then the register website is open.

The code I have used for the onInstall is:

          browser.runtime.onInstalled.addListener(function handleInstalled(details) {
          if(details.reason == "install"){
              browser.tabs.create({
                  url: registerUrl,
              });
          }
          else if(details.reason == "update"){
              browser.tabs.create({
                  url: activateUrl,
              });
          }
      });

Looks like this is a known issue tracked by bug 1911998. The desktop version was recently fixed in bug 1842832.

Short term, you can work around this issue by opening a tab at install time to a https:// URL rather than a page inside the extension.

3 Likes

Thank you for your answer. That might work, however, would require some rework. Is it not possible to call another like onInstall function after accepting the privacy mode? Forexample onPermission or similar?

I can’t think of another reliable workaround.

Private browsing settings aren’t exposed in the permissions API, so the permissions.onAdded or permissions.onRemoved events won’t be useful here. Temporarily installed extensions will receive a runtime.onInstalled event when toggling private browsing settings, but that’s because reloading a temporary extension causes that event to fire.

1 Like

I just thought of a workaround. The extension.isAllowedIncognitoAccess() method will asynchronously tell you whether the extension can access incognito pages. If you combine this with some data written to storage.local, you can set up some logic to reopen the extension’s welcome page when the user toggles private browsing access.

In this example, we only open a new tab if the user toggles the private browsing setting within the first 20 seconds of installing the extension. Tweak to your liking.

function showOnboarding() {
  // "manifest.json" is only used here for demo purposes
  browser.tabs.create({ url: browser.runtime.getURL("manifest.json") });
}

browser.runtime.onInstalled.addListener(async (info) => {
  if (info.reason === "install") {
    browser.storage.local.set({ installTimestamp: Date.now() });
  }
});

async function onPrivateBrowsingChange(callback) {
  const MAX_SECONDS_SINCE_INSTALL = 20;

  const storageLocalPromise = browser.storage.local.get({
    // Assume private browsing access is not granted on first install
    privateBrowsingAccess: false,
    // Defaulting to epoch ensures this check fails on first install
    installTimestamp: 0,
  });

  const privateAccessPromise = browser.extension.isAllowedIncognitoAccess();

  // Combining promises into a single await reduces total time spent waiting
  const [data, hasPrivateAccess] = await Promise.all([
    storageLocalPromise,
    privateAccessPromise,
  ]);

  // Cache the current value for the next check
  browser.storage.local.set({privateBrowsingAccess: hasPrivateAccess});

  const privateAccessChanged = hasPrivateAccess !== data.privateBrowsingAccess;
  const secondsSinceInstall = (Date.now() - data.installTimestamp) / 1000;
  if (privateAccessChanged && secondsSinceInstall < MAX_SECONDS_SINCE_INSTALL) {
    callback();
  }
}
onPrivateBrowsingChange(showOnboarding);
1 Like