Closed Bug 1822763 Opened 1 year ago Closed 1 year ago

Listen to AddonManager events

Categories

(GeckoView :: Extensions, enhancement, P3)

All
Android
enhancement

Tracking

(firefox112 wontfix, firefox113 fixed)

RESOLVED FIXED
113 Branch
Tracking Status
firefox112 --- wontfix
firefox113 --- fixed

People

(Reporter: willdurand, Assigned: willdurand)

References

Details

(Whiteboard: [addons-jira])

Attachments

(3 files)

The idea here is to implement an AddonListener in GeckoView that we would automatically register using the addAddonListener() method in order to listen to events such as onUninstalled(), onDisabled(), onEnabled(), etc. These events are not "install" events, they are emitted by the AddonManager for various reasons.

This is how I see the implementation in mobile/android/modules/geckoview/GeckoViewWebExtension.jsm:

class ExtensionAddonListener {
  constructor() {
    lazy.AddonManager.addAddonListener(this);
  }

  async onDisabled(aAddon) {
    debug`onDisabled ${aAddon.id}`;

    const extension = await exportExtension(
      aAddon,
      aAddon.userPermissions,
      /* aSourceURI */ null
    );
    lazy.EventDispatcher.instance.sendRequestForResult({
      type: "GeckoView:WebExtension:OnDisabled",
      extension,
    });
  }

  // TODO: handle more events
}

new ExtensionAddonListener();

Each supported event should send a request, e.g., onDisabled() would send the GeckoView:WebExtension:OnDisabled request, which the WebExtensionController would have to handle. This might require a new delegate (AddonManagerDelegate?) that would "simply" pass the information to the embedder:

public class WebExtensionController {
  // ...

  private AddonManagerDelegate mAddonManagerDelegate;
  
  public interface AddonManagerDelegate {
    @Nullable
    default void onDisabled(final @NonNull WebExtension extension) {}
  }

  // ...

  void handleMessage(...) {
    // ...

    if ("GeckoView:WebExtension:OnDisabled".equals(event)) {
      final GeckoBundle anExtensionBundle = bundle.getBundle("extension");
      final WebExtension anExtension = new WebExtension(
        mDelegateControllerProvider,
        anExtensionBundle
      );
      mAddonManagerDelegate.onDisabled(anExtension);
      return;
    }
  }
}

We need to listen to these events in order to support new install flows (e.g. using mozAddonManager) but also to reflect changes to an add-on to the embedder (e.g. if we block an add-on, we want to make sure the app will no longer show the add-on as installed/enabled).

This is the first step to listen to other AddonManager events. We likely
need a new delegate because there is no other existing delegate we can
leverage I think.

In Fenix, we could use this new delegate like this:

diff --git a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt
index 5d34a952e8..8031bd1f67 100644
--- a/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt
+++ b/android-components/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngine.kt
@@ -357,8 +357,15 @@ class GeckoEngine(
             }
         }

-        runtime.webExtensionController.promptDelegate = promptDelegate
+        val addonManagerDelegate = object : WebExtensionController.AddonManagerDelegate {
+            override fun onDisabled(extension: org.mozilla.geckoview.WebExtension) {
+                webExtensionDelegate.onDisabled(GeckoWebExtension(extension, runtime))
+            }
+        }
+
+        runtime.webExtensionController.setPromptDelegate(promptDelegate)
         runtime.webExtensionController.setDebuggerDelegate(debuggerDelegate)
+        runtime.webExtensionController.setAddonManagerDelegate(addonManagerDelegate)
     }

     /**
@@ -422,7 +429,6 @@ class GeckoEngine(
         runtime.webExtensionController.disable((extension as GeckoWebExtension).nativeExtension, source.id).then(
             {
                 val disabledExtension = GeckoWebExtension(it!!, runtime)
-                webExtensionDelegate?.onDisabled(disabledExtension)
                 onSuccess(disabledExtension)
                 GeckoResult<Void>()
             },
Assignee: nobody → wdurand
Status: NEW → ASSIGNED
Blocks: 1824863
Attachment #9325446 - Attachment description: WIP: Bug 1822763 - Listen to AddonManager "onDisabled" event. → Bug 1822763 - Listen to AddonManager "onDisabled" event. r?zmckenney!,rpl!
Blocks: 1825120
Blocks: 1825130

Depends on D173835

Depends on D173835

For completeness, I added this event too.

Depends on D174466

Pushed by wdurand@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/e69ce1b32ff2
Listen to AddonManager "onDisabled" event. r=geckoview-reviewers,zmckenney,rpl,amejiamarmol
https://hg.mozilla.org/integration/autoland/rev/152d4079f316
Listen to AddonManager "onEnabled" event. r=zmckenney,rpl,geckoview-reviewers
https://hg.mozilla.org/integration/autoland/rev/2fa13aa9553d
Listen to AddonManager "onUninstalled" event. r=zmckenney,rpl,geckoview-reviewers,calu,amejiamarmol

Sorry about that, I noticed (new?) failures locally as well and was about to push another commit.. Anyway, I'll update the patches and re-land the stack once I get a green try push.

Flags: needinfo?(wdurand)

There are also these: https://treeherder.mozilla.org/logviewer?job_id=411335898&repo=autoland and all the xpcshell failures look to be Android only.

Pushed by wdurand@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/87701a14d81d
Listen to AddonManager "onDisabled" event. r=geckoview-reviewers,zmckenney,rpl,amejiamarmol
https://hg.mozilla.org/integration/autoland/rev/0c59791435ce
Listen to AddonManager "onEnabled" event. r=zmckenney,rpl,geckoview-reviewers,amejiamarmol
https://hg.mozilla.org/integration/autoland/rev/9c4e16dbfdff
Listen to AddonManager "onUninstalled" event. r=zmckenney,rpl,geckoview-reviewers,calu,amejiamarmol
Pushed by wdurand@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/52079267cc83
Listen to AddonManager "onDisabled" event. r=geckoview-reviewers,zmckenney,rpl,amejiamarmol
https://hg.mozilla.org/integration/autoland/rev/e135887f1a8c
Listen to AddonManager "onEnabled" event. r=zmckenney,rpl,geckoview-reviewers,amejiamarmol
https://hg.mozilla.org/integration/autoland/rev/834ccb7b14b1
Listen to AddonManager "onUninstalled" event. r=zmckenney,rpl,geckoview-reviewers,calu,amejiamarmol
Flags: needinfo?(wdurand)
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 113 Branch
Blocks: 1826739
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: