зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1600742 - Move event listeners from WebExtension to WebExtensionController. r=snorp,esawin
Differential Revision: https://phabricator.services.mozilla.com/D57035 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6c81d2a85b
Коммит
f8d68e46e1
|
@ -68,28 +68,14 @@ public class WebExtension {
|
|||
/* package */ interface DelegateController {
|
||||
void onMessageDelegate(final String nativeApp, final MessageDelegate delegate);
|
||||
void onActionDelegate(final ActionDelegate delegate);
|
||||
ActionDelegate getActionDelegate();
|
||||
}
|
||||
|
||||
private WeakReference<DelegateController> mDelegateController = new WeakReference<>(null);
|
||||
private DelegateController mDelegateController = null;
|
||||
|
||||
/* package */ void setDelegateController(final DelegateController observer) {
|
||||
mDelegateController = new WeakReference<>(observer);
|
||||
|
||||
if (observer != null) {
|
||||
// Notify observers of already attached delegates
|
||||
for (final Map.Entry<String, MessageDelegate> entry : messageDelegates.entrySet()) {
|
||||
observer.onMessageDelegate(entry.getKey(), entry.getValue());
|
||||
/* package */ void setDelegateController(final DelegateController delegate) {
|
||||
mDelegateController = delegate;
|
||||
}
|
||||
observer.onActionDelegate(actionDelegate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates that handle messaging between this WebExtension and the app.
|
||||
*/
|
||||
/* package */ final @NonNull Map<String, MessageDelegate> messageDelegates;
|
||||
|
||||
/* package */ @NonNull ActionDelegate actionDelegate;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -128,7 +114,6 @@ public class WebExtension {
|
|||
flags = bundle.getInt("webExtensionFlags", 0);
|
||||
isBuiltIn = bundle.getBoolean("isBuiltIn", false);
|
||||
isEnabled = bundle.getBoolean("isEnabled", false);
|
||||
messageDelegates = new HashMap<>();
|
||||
if (bundle.containsKey("metaData")) {
|
||||
metaData = new MetaData(bundle.getBundle("metaData"));
|
||||
} else {
|
||||
|
@ -164,10 +149,10 @@ public class WebExtension {
|
|||
public WebExtension(final @NonNull String location, final @NonNull String id,
|
||||
final @WebExtensionFlags long flags,
|
||||
final @NonNull WebExtensionController controller) {
|
||||
setDelegateController(controller.delegateFor(this));
|
||||
this.location = location;
|
||||
this.id = id;
|
||||
this.flags = flags;
|
||||
this.messageDelegates = new HashMap<>();
|
||||
|
||||
// TODO:
|
||||
this.isEnabled = false;
|
||||
|
@ -244,15 +229,9 @@ public class WebExtension {
|
|||
@UiThread
|
||||
public void setMessageDelegate(final @Nullable MessageDelegate messageDelegate,
|
||||
final @NonNull String nativeApp) {
|
||||
final DelegateController observer = mDelegateController.get();
|
||||
if (observer != null) {
|
||||
observer.onMessageDelegate(nativeApp, messageDelegate);
|
||||
if (mDelegateController != null) {
|
||||
mDelegateController.onMessageDelegate(nativeApp, messageDelegate);
|
||||
}
|
||||
if (messageDelegate == null) {
|
||||
messageDelegates.remove(nativeApp);
|
||||
return;
|
||||
}
|
||||
messageDelegates.put(nativeApp, messageDelegate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -468,6 +447,8 @@ public class WebExtension {
|
|||
/* package */ final static class Listener implements BundleEventListener {
|
||||
final private HashMap<Sender, WebExtension.MessageDelegate> mMessageDelegates;
|
||||
final private HashMap<String, WebExtension.ActionDelegate> mActionDelegates;
|
||||
private WebExtensionController.TabDelegate mTabDelegate = null;
|
||||
|
||||
final private GeckoSession mSession;
|
||||
final private EventDispatcher mEventDispatcher;
|
||||
|
||||
|
@ -498,6 +479,28 @@ public class WebExtension {
|
|||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
public void setTabDelegate(final WebExtensionController.TabDelegate delegate) {
|
||||
if (delegate != null && mTabDelegate == null) {
|
||||
mEventDispatcher.registerUiThreadListener(
|
||||
this,
|
||||
"GeckoView:WebExtension:NewTab",
|
||||
"GeckoView:WebExtension:CloseTab"
|
||||
);
|
||||
} else if (delegate == null && mTabDelegate != null) {
|
||||
mEventDispatcher.unregisterUiThreadListener(
|
||||
this,
|
||||
"GeckoView:WebExtension:NewTab",
|
||||
"GeckoView:WebExtension:CloseTab"
|
||||
);
|
||||
}
|
||||
|
||||
mTabDelegate = delegate;
|
||||
}
|
||||
|
||||
public WebExtensionController.TabDelegate getTabDelegate() {
|
||||
return mTabDelegate;
|
||||
}
|
||||
|
||||
public void setActionDelegate(final WebExtension webExtension,
|
||||
final WebExtension.ActionDelegate delegate) {
|
||||
if (!mActionDelegateRegistered && delegate != null) {
|
||||
|
@ -555,10 +558,30 @@ public class WebExtension {
|
|||
|| "GeckoView:BrowserAction:OpenPopup".equals(event)) {
|
||||
controller.handleMessage(event, message, callback, mSession);
|
||||
return;
|
||||
} else if ("GeckoView:WebExtension:CloseTab".equals(event)) {
|
||||
controller.closeTab(message, callback, mSession);
|
||||
}
|
||||
|
||||
// If a tab delegate is not defined on the session, try the runtime
|
||||
//
|
||||
// TODO: The tab delegate is special because it's only set on the
|
||||
// controller and not on the session, all other delegates are set
|
||||
// on both, we should unify this and have a tab delegate for each
|
||||
// session too.
|
||||
WebExtensionController.TabDelegate delegate = mTabDelegate;
|
||||
if (delegate == null && mSession != null) {
|
||||
delegate = runtime.getWebExtensionController().getTabDelegate();
|
||||
}
|
||||
|
||||
if (delegate == null) {
|
||||
callback.sendError("No delegate registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ("GeckoView:WebExtension:CloseTab".equals(event)) {
|
||||
controller.closeTab(message, callback, delegate, mSession);
|
||||
return;
|
||||
} else if ("GeckoView:WebExtension:NewTab".equals(event)) {
|
||||
controller.newTab(message, callback, delegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -941,12 +964,12 @@ public class WebExtension {
|
|||
@UiThread
|
||||
public void click() {
|
||||
if (mPopupUri != null && !mPopupUri.isEmpty()) {
|
||||
if (mExtension.actionDelegate == null) {
|
||||
final ActionDelegate delegate = mExtension.mDelegateController.getActionDelegate();
|
||||
if (delegate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
GeckoResult<GeckoSession> popup =
|
||||
mExtension.actionDelegate.onTogglePopup(mExtension, this);
|
||||
GeckoResult<GeckoSession> popup = delegate.onTogglePopup(mExtension, this);
|
||||
openPopup(popup);
|
||||
|
||||
// When popupUri is specified, the extension doesn't get a callback
|
||||
|
@ -1143,13 +1166,10 @@ public class WebExtension {
|
|||
*/
|
||||
@AnyThread
|
||||
public void setActionDelegate(final @Nullable ActionDelegate delegate) {
|
||||
final DelegateController observer = mDelegateController.get();
|
||||
if (observer != null) {
|
||||
observer.onActionDelegate(delegate);
|
||||
if (mDelegateController != null) {
|
||||
mDelegateController.onActionDelegate(delegate);
|
||||
}
|
||||
|
||||
actionDelegate = delegate;
|
||||
|
||||
final GeckoBundle bundle = new GeckoBundle(1);
|
||||
bundle.putString("extensionId", id);
|
||||
|
||||
|
|
|
@ -21,10 +21,8 @@ import java.util.Map;
|
|||
public class WebExtensionController {
|
||||
private final static String LOGTAG = "WebExtension";
|
||||
|
||||
private GeckoRuntime mRuntime;
|
||||
|
||||
private TabDelegate mTabDelegate;
|
||||
private PromptDelegate mPromptDelegate;
|
||||
private final WebExtension.Listener mListener;
|
||||
|
||||
private static class ExtensionStore {
|
||||
final private Map<String, WebExtension> mData = new HashMap<>();
|
||||
|
@ -66,11 +64,7 @@ public class WebExtensionController {
|
|||
|
||||
// Avoids exposing listeners to the API
|
||||
private class Internals implements BundleEventListener,
|
||||
WebExtension.Port.DisconnectDelegate,
|
||||
WebExtension.DelegateController {
|
||||
private boolean mMessageListenersAttached = false;
|
||||
private boolean mActionListenersAttached = false;
|
||||
|
||||
WebExtension.Port.DisconnectDelegate {
|
||||
@Override
|
||||
// BundleEventListener
|
||||
public void handleMessage(final String event, final GeckoBundle message,
|
||||
|
@ -85,35 +79,35 @@ public class WebExtensionController {
|
|||
// we just need to remove it from our list of ports.
|
||||
mPorts.remove(port.id);
|
||||
}
|
||||
}
|
||||
|
||||
private class DelegateController implements WebExtension.DelegateController {
|
||||
private WebExtension mExtension;
|
||||
|
||||
public DelegateController(final WebExtension extension) {
|
||||
mExtension = extension;
|
||||
}
|
||||
|
||||
@Override
|
||||
// WebExtension.DelegateController
|
||||
public void onMessageDelegate(final String nativeApp,
|
||||
final WebExtension.MessageDelegate delegate) {
|
||||
if (delegate != null && !mMessageListenersAttached) {
|
||||
EventDispatcher.getInstance().registerUiThreadListener(
|
||||
this,
|
||||
"GeckoView:WebExtension:Message",
|
||||
"GeckoView:WebExtension:PortMessage",
|
||||
"GeckoView:WebExtension:Connect",
|
||||
"GeckoView:WebExtension:Disconnect");
|
||||
mMessageListenersAttached = true;
|
||||
}
|
||||
mListener.setMessageDelegate(mExtension, delegate, nativeApp);
|
||||
}
|
||||
|
||||
@Override
|
||||
// WebExtension.DelegateController
|
||||
public void onActionDelegate(final WebExtension.ActionDelegate delegate) {
|
||||
if (delegate != null && !mActionListenersAttached) {
|
||||
EventDispatcher.getInstance().registerUiThreadListener(
|
||||
this,
|
||||
"GeckoView:BrowserAction:Update",
|
||||
"GeckoView:BrowserAction:OpenPopup",
|
||||
"GeckoView:PageAction:Update",
|
||||
"GeckoView:PageAction:OpenPopup");
|
||||
mActionListenersAttached = true;
|
||||
mListener.setActionDelegate(mExtension, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebExtension.ActionDelegate getActionDelegate() {
|
||||
return mListener.getActionDelegate(mExtension);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove once we remove GeckoRuntime#registerWebExtension
|
||||
/* package */ DelegateController delegateFor(final WebExtension extension) {
|
||||
return new DelegateController(extension);
|
||||
}
|
||||
|
||||
public interface TabDelegate {
|
||||
|
@ -155,27 +149,12 @@ public class WebExtensionController {
|
|||
|
||||
@UiThread
|
||||
public @Nullable TabDelegate getTabDelegate() {
|
||||
return mTabDelegate;
|
||||
return mListener.getTabDelegate();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void setTabDelegate(final @Nullable TabDelegate delegate) {
|
||||
if (delegate == null) {
|
||||
if (mTabDelegate != null) {
|
||||
EventDispatcher.getInstance().unregisterUiThreadListener(
|
||||
mInternals,
|
||||
"GeckoView:WebExtension:NewTab"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (mTabDelegate == null) {
|
||||
EventDispatcher.getInstance().registerUiThreadListener(
|
||||
mInternals,
|
||||
"GeckoView:WebExtension:NewTab"
|
||||
);
|
||||
}
|
||||
}
|
||||
mTabDelegate = delegate;
|
||||
mListener.setTabDelegate(delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -454,20 +433,17 @@ public class WebExtensionController {
|
|||
}
|
||||
|
||||
/* package */ WebExtensionController(final GeckoRuntime runtime) {
|
||||
mRuntime = runtime;
|
||||
mListener = new WebExtension.Listener(runtime);
|
||||
}
|
||||
|
||||
/* package */ void registerWebExtension(final WebExtension webExtension) {
|
||||
webExtension.setDelegateController(mInternals);
|
||||
webExtension.setDelegateController(new DelegateController(webExtension));
|
||||
mExtensions.put(webExtension.id, webExtension);
|
||||
}
|
||||
|
||||
/* package */ void handleMessage(final String event, final GeckoBundle message,
|
||||
final EventCallback callback, final GeckoSession session) {
|
||||
if ("GeckoView:WebExtension:NewTab".equals(event)) {
|
||||
newTab(message, callback);
|
||||
return;
|
||||
} else if ("GeckoView:WebExtension:Disconnect".equals(event)) {
|
||||
if ("GeckoView:WebExtension:Disconnect".equals(event)) {
|
||||
disconnect(message.getLong("portId", -1), callback);
|
||||
return;
|
||||
} else if ("GeckoView:WebExtension:PortMessage".equals(event)) {
|
||||
|
@ -532,6 +508,7 @@ public class WebExtensionController {
|
|||
}
|
||||
|
||||
final WebExtension extension = new WebExtension(extensionBundle);
|
||||
extension.setDelegateController(new DelegateController(extension));
|
||||
|
||||
if (mPromptDelegate == null) {
|
||||
Log.e(LOGTAG, "Tried to install extension " + extension.id +
|
||||
|
@ -555,14 +532,10 @@ public class WebExtensionController {
|
|||
});
|
||||
}
|
||||
|
||||
private void newTab(final GeckoBundle message, final EventCallback callback) {
|
||||
if (mTabDelegate == null) {
|
||||
callback.sendSuccess(null);
|
||||
return;
|
||||
}
|
||||
|
||||
/* package */ void newTab(final GeckoBundle message, final EventCallback callback,
|
||||
final TabDelegate delegate) {
|
||||
mExtensions.get(message.getString("extensionId")).then(extension ->
|
||||
mTabDelegate.onNewTab(extension, message.getString("uri"))
|
||||
delegate.onNewTab(extension, message.getString("uri"))
|
||||
).accept(session -> {
|
||||
if (session == null) {
|
||||
callback.sendSuccess(null);
|
||||
|
@ -573,24 +546,22 @@ public class WebExtensionController {
|
|||
throw new IllegalArgumentException("Must use an unopened GeckoSession instance");
|
||||
}
|
||||
|
||||
session.open(mRuntime);
|
||||
session.open(mListener.runtime);
|
||||
|
||||
callback.sendSuccess(session.getId());
|
||||
});
|
||||
}
|
||||
|
||||
/* package */ void closeTab(final GeckoBundle message, final EventCallback callback, final GeckoSession session) {
|
||||
if (mTabDelegate == null) {
|
||||
callback.sendError(null);
|
||||
return;
|
||||
}
|
||||
|
||||
/* package */ void closeTab(final GeckoBundle message,
|
||||
final EventCallback callback,
|
||||
final TabDelegate delegate,
|
||||
final GeckoSession session) {
|
||||
mExtensions.get(message.getString("extensionId")).then(
|
||||
extension -> mTabDelegate.onCloseTab(extension, session),
|
||||
extension -> delegate.onCloseTab(extension, session),
|
||||
// On uninstall, we close all extension pages, in that case
|
||||
// the extension object may be gone already so we can't
|
||||
// send it to the delegate
|
||||
exception -> mTabDelegate.onCloseTab(null, session)
|
||||
exception -> delegate.onCloseTab(null, session)
|
||||
).accept(value -> {
|
||||
if (value == AllowOrDeny.ALLOW) {
|
||||
callback.sendSuccess(null);
|
||||
|
@ -701,7 +672,7 @@ public class WebExtensionController {
|
|||
if (sender.session != null) {
|
||||
delegate = sender.session.getMessageDelegate(sender.webExtension, nativeApp);
|
||||
} else if (sender.environmentType == WebExtension.MessageSender.ENV_TYPE_EXTENSION) {
|
||||
delegate = sender.webExtension.messageDelegates.get(nativeApp);
|
||||
delegate = mListener.getMessageDelegate(sender.webExtension, nativeApp);
|
||||
}
|
||||
|
||||
if (delegate == null) {
|
||||
|
@ -805,7 +776,7 @@ public class WebExtensionController {
|
|||
private WebExtension.ActionDelegate actionDelegateFor(final WebExtension extension,
|
||||
final GeckoSession session) {
|
||||
if (session == null) {
|
||||
return extension.actionDelegate;
|
||||
return mListener.getActionDelegate(extension);
|
||||
}
|
||||
|
||||
return session.getWebExtensionActionDelegate(extension);
|
||||
|
|
Загрузка…
Ссылка в новой задаче