зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1599585 - Implement enable/disable extensions. r=esawin,snorp
Differential Revision: https://phabricator.services.mozilla.com/D58859 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
dcd4934531
Коммит
6ac412a45a
|
@ -1484,6 +1484,12 @@ package org.mozilla.geckoview {
|
|||
field public static final int VULNERABLE_UPDATE_AVAILABLE = 4;
|
||||
}
|
||||
|
||||
public static class WebExtension.DisabledFlags {
|
||||
ctor public DisabledFlags();
|
||||
field public static final int BLOCKLIST_DISABLED = 4;
|
||||
field public static final int USER_DISABLED = 2;
|
||||
}
|
||||
|
||||
public static class WebExtension.Flags {
|
||||
ctor protected Flags();
|
||||
field public static final long ALLOW_CONTENT_MESSAGING = 1L;
|
||||
|
@ -1533,6 +1539,8 @@ package org.mozilla.geckoview {
|
|||
field @Nullable public final String creatorName;
|
||||
field @Nullable public final String creatorUrl;
|
||||
field @Nullable public final String description;
|
||||
field public final int disabledFlags;
|
||||
field public final boolean enabled;
|
||||
field @Nullable public final String homepageUrl;
|
||||
field @NonNull public final WebExtension.Icon icon;
|
||||
field public final boolean isRecommended;
|
||||
|
@ -1568,6 +1576,8 @@ package org.mozilla.geckoview {
|
|||
}
|
||||
|
||||
public class WebExtensionController {
|
||||
method @AnyThread @NonNull public GeckoResult<WebExtension> disable(@NonNull WebExtension, int);
|
||||
method @AnyThread @NonNull public GeckoResult<WebExtension> enable(@NonNull WebExtension, int);
|
||||
method @UiThread @Nullable public WebExtensionController.PromptDelegate getPromptDelegate();
|
||||
method @UiThread @Nullable public WebExtensionController.TabDelegate getTabDelegate();
|
||||
method @NonNull @AnyThread public GeckoResult<WebExtension> install(@NonNull String);
|
||||
|
@ -1577,6 +1587,11 @@ package org.mozilla.geckoview {
|
|||
method @NonNull @AnyThread public GeckoResult<Void> uninstall(@NonNull WebExtension);
|
||||
}
|
||||
|
||||
public static class WebExtensionController.EnableSource {
|
||||
ctor public EnableSource();
|
||||
field public static final int USER = 1;
|
||||
}
|
||||
|
||||
@UiThread public static interface WebExtensionController.PromptDelegate {
|
||||
method @Nullable default public GeckoResult<AllowOrDeny> onInstallPrompt(@NonNull WebExtension);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
package org.mozilla.geckoview.test
|
||||
|
||||
import android.support.test.InstrumentationRegistry
|
||||
|
||||
import android.support.test.filters.MediumTest
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
import org.hamcrest.core.StringEndsWith.endsWith
|
||||
|
@ -23,8 +21,8 @@ import org.mozilla.geckoview.*
|
|||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
|
||||
import org.mozilla.geckoview.test.util.Callbacks
|
||||
import org.mozilla.geckoview.test.util.TestServer
|
||||
import java.net.URI
|
||||
import org.mozilla.geckoview.WebExtension.DisabledFlags
|
||||
import org.mozilla.geckoview.WebExtensionController.EnableSource
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
|
@ -64,9 +62,7 @@ class WebExtensionTest : BaseSessionTest() {
|
|||
|
||||
// First let's check that the color of the border is empty before loading
|
||||
// the WebExtension
|
||||
val colorBefore = mainSession.evaluateJS("document.body.style.borderColor")
|
||||
assertThat("The border color should be empty when loading without extensions.",
|
||||
colorBefore as String, equalTo(""))
|
||||
assertBodyBorderEqualTo("")
|
||||
|
||||
val borderify = WebExtension("resource://android/assets/web_extensions/borderify/",
|
||||
controller)
|
||||
|
@ -78,9 +74,7 @@ class WebExtensionTest : BaseSessionTest() {
|
|||
sessionRule.waitForPageStop()
|
||||
|
||||
// Check that the WebExtension was applied by checking the border color
|
||||
val color = mainSession.evaluateJS("document.body.style.borderColor")
|
||||
assertThat("Content script should have been applied",
|
||||
color as String, equalTo("red"))
|
||||
assertBodyBorderEqualTo("red")
|
||||
|
||||
// Unregister WebExtension and check again
|
||||
sessionRule.waitForResult(sessionRule.runtime.unregisterWebExtension(borderify))
|
||||
|
@ -89,9 +83,74 @@ class WebExtensionTest : BaseSessionTest() {
|
|||
sessionRule.waitForPageStop()
|
||||
|
||||
// Check that the WebExtension was not applied after being unregistered
|
||||
val colorAfter = mainSession.evaluateJS("document.body.style.borderColor")
|
||||
assertThat("Content script should have been applied",
|
||||
colorAfter as String, equalTo(""))
|
||||
assertBodyBorderEqualTo("")
|
||||
}
|
||||
|
||||
private fun assertBodyBorderEqualTo(expected: String) {
|
||||
val color = mainSession.evaluateJS("document.body.style.borderColor")
|
||||
assertThat("The border color should be '$expected'",
|
||||
color as String, equalTo(expected))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun enableDisable() {
|
||||
mainSession.loadUri("example.com")
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
sessionRule.delegateDuringNextWait(object : WebExtensionController.PromptDelegate {
|
||||
@AssertCalled
|
||||
override fun onInstallPrompt(extension: WebExtension): GeckoResult<AllowOrDeny> {
|
||||
return GeckoResult.fromValue(AllowOrDeny.ALLOW)
|
||||
}
|
||||
})
|
||||
|
||||
// First let's check that the color of the border is empty before loading
|
||||
// the WebExtension
|
||||
assertBodyBorderEqualTo("")
|
||||
|
||||
var borderify = sessionRule.waitForResult(
|
||||
controller.install("resource://android/assets/web_extensions/borderify.xpi"))
|
||||
mainSession.reload()
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
assertThat("Extension should be enabled after installing", borderify.metaData!!.enabled,
|
||||
equalTo(true))
|
||||
assertThat("Extension should be user disabled after calling disable",
|
||||
borderify.metaData!!.disabledFlags, equalTo(0))
|
||||
// Border should be ready because the extension is enabled
|
||||
assertBodyBorderEqualTo("red")
|
||||
|
||||
borderify = sessionRule.waitForResult(controller.disable(borderify, EnableSource.USER))
|
||||
mainSession.reload()
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
assertThat("Extension should be user disabled after calling disable",
|
||||
borderify.metaData!!.enabled, equalTo(false))
|
||||
assertThat("Extension should be user disabled after calling disable",
|
||||
borderify.metaData!!.disabledFlags and DisabledFlags.USER_DISABLED > 0,
|
||||
equalTo(true))
|
||||
assertThat("Extension should not be blocklist disabled after calling disable",
|
||||
borderify.metaData!!.disabledFlags and DisabledFlags.BLOCKLIST_DISABLED > 0,
|
||||
equalTo(false))
|
||||
// Border should be empty because the extension is disabled
|
||||
assertBodyBorderEqualTo("")
|
||||
|
||||
borderify = sessionRule.waitForResult(controller.enable(borderify, EnableSource.USER))
|
||||
mainSession.reload()
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
assertThat("Extension should be user disabled after calling disable",
|
||||
borderify.metaData!!.enabled, equalTo(true))
|
||||
assertThat("Extension should be user disabled after calling disable",
|
||||
borderify.metaData!!.disabledFlags, equalTo(0))
|
||||
assertBodyBorderEqualTo("red")
|
||||
|
||||
sessionRule.waitForResult(controller.uninstall(borderify))
|
||||
mainSession.reload()
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
// Border should be empty because the extension is not installed anymore
|
||||
assertBodyBorderEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -101,9 +160,7 @@ class WebExtensionTest : BaseSessionTest() {
|
|||
|
||||
// First let's check that the color of the border is empty before loading
|
||||
// the WebExtension
|
||||
val colorBefore = mainSession.evaluateJS("document.body.style.borderColor")
|
||||
assertThat("The border color should be empty when loading without extensions.",
|
||||
colorBefore as String, equalTo(""))
|
||||
assertBodyBorderEqualTo("")
|
||||
|
||||
sessionRule.delegateDuringNextWait(object : WebExtensionController.PromptDelegate {
|
||||
@AssertCalled
|
||||
|
@ -114,8 +171,7 @@ class WebExtensionTest : BaseSessionTest() {
|
|||
assertEquals(extension.metaData!!.version, "1.0")
|
||||
// TODO: Bug 1601067
|
||||
// assertEquals(extension.isBuiltIn, false)
|
||||
// TODO: Bug 1599585
|
||||
// assertEquals(extension.isEnabled, false)
|
||||
assertEquals(extension.metaData!!.enabled, true)
|
||||
assertEquals(extension.metaData!!.signedState,
|
||||
WebExtension.SignedStateFlags.SIGNED)
|
||||
assertEquals(extension.metaData!!.blocklistState,
|
||||
|
@ -132,9 +188,7 @@ class WebExtensionTest : BaseSessionTest() {
|
|||
sessionRule.waitForPageStop()
|
||||
|
||||
// Check that the WebExtension was applied by checking the border color
|
||||
val color = mainSession.evaluateJS("document.body.style.borderColor")
|
||||
assertThat("Content script should have been applied",
|
||||
color as String, equalTo("red"))
|
||||
assertBodyBorderEqualTo("red")
|
||||
|
||||
var list = sessionRule.waitForResult(controller.list())
|
||||
assertEquals(list.size, 1)
|
||||
|
@ -150,9 +204,7 @@ class WebExtensionTest : BaseSessionTest() {
|
|||
sessionRule.waitForPageStop()
|
||||
|
||||
// Check that the WebExtension was not applied after being unregistered
|
||||
val colorAfter = mainSession.evaluateJS("document.body.style.borderColor")
|
||||
assertThat("Content script should have been applied",
|
||||
colorAfter as String, equalTo(""))
|
||||
assertBodyBorderEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -61,9 +61,6 @@ public class WebExtension {
|
|||
// TODO: make public
|
||||
final boolean isBuiltIn;
|
||||
|
||||
// TODO: make public
|
||||
final boolean isEnabled;
|
||||
|
||||
/** Called whenever a delegate is set or unset on this {@link WebExtension} instance.
|
||||
/* package */ interface DelegateController {
|
||||
void onMessageDelegate(final String nativeApp, final MessageDelegate delegate);
|
||||
|
@ -113,7 +110,6 @@ public class WebExtension {
|
|||
id = bundle.getString("webExtensionId");
|
||||
flags = bundle.getInt("webExtensionFlags", 0);
|
||||
isBuiltIn = bundle.getBoolean("isBuiltIn", false);
|
||||
isEnabled = bundle.getBoolean("isEnabled", false);
|
||||
if (bundle.containsKey("metaData")) {
|
||||
metaData = new MetaData(bundle.getBundle("metaData"));
|
||||
} else {
|
||||
|
@ -155,7 +151,6 @@ public class WebExtension {
|
|||
this.flags = flags;
|
||||
|
||||
// TODO:
|
||||
this.isEnabled = false;
|
||||
this.isBuiltIn = false;
|
||||
this.metaData = null;
|
||||
}
|
||||
|
@ -1223,6 +1218,23 @@ public class WebExtension {
|
|||
BlocklistStateFlags.VULNERABLE_NO_UPDATE})
|
||||
@interface BlocklistState {}
|
||||
|
||||
public static class DisabledFlags {
|
||||
/** The extension has been disabled by the user */
|
||||
public final static int USER_DISABLED = 1 << 1;
|
||||
|
||||
/** The extension has been disabled by the blocklist. The details of why this extension
|
||||
* was blocked can be found in {@link MetaData#blocklistState}. */
|
||||
public final static int BLOCKLIST_DISABLED = 1 << 2;
|
||||
|
||||
// TODO: Bug 1604222
|
||||
final static int APP_DISABLED = 1 << 3;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true,
|
||||
value = { DisabledFlags.USER_DISABLED, DisabledFlags.BLOCKLIST_DISABLED })
|
||||
@interface EnabledFlags {}
|
||||
|
||||
/** Provides information about a {@link WebExtension}. */
|
||||
public class MetaData {
|
||||
/** Main {@link Icon} branding for this {@link WebExtension}.
|
||||
|
@ -1324,6 +1336,27 @@ public class WebExtension {
|
|||
*/
|
||||
public final @SignedState int signedState;
|
||||
|
||||
/**
|
||||
* Disabled binary flags for this extension.
|
||||
*
|
||||
* This will be either equal to <code>0</code> if the extension
|
||||
* is enabled or will contain one or more flags from {@link DisabledFlags}.
|
||||
*
|
||||
* e.g. if the extension has been disabled by the user, the value in
|
||||
* {@link DisabledFlags#USER_DISABLED} will be equal to <code>1</code>:
|
||||
*
|
||||
* <pre><code>
|
||||
* boolean isUserDisabled = metaData.disabledFlags
|
||||
* & DisabledFlags.USER_DISABLED > 0;
|
||||
* </code></pre>
|
||||
*/
|
||||
public final @EnabledFlags int disabledFlags;
|
||||
|
||||
/**
|
||||
* Whether this extension is enabled or not.
|
||||
*/
|
||||
public final boolean enabled;
|
||||
|
||||
/** Override for testing. */
|
||||
protected MetaData() {
|
||||
icon = null;
|
||||
|
@ -1340,6 +1373,8 @@ public class WebExtension {
|
|||
isRecommended = false;
|
||||
blocklistState = BlocklistStateFlags.NOT_BLOCKED;
|
||||
signedState = SignedStateFlags.UNKNOWN;
|
||||
disabledFlags = 0;
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
/* package */ MetaData(final GeckoBundle bundle) {
|
||||
|
@ -1364,6 +1399,21 @@ public class WebExtension {
|
|||
this.signedState = SignedStateFlags.UNKNOWN;
|
||||
}
|
||||
|
||||
int disabledFlags = 0;
|
||||
final String[] disabledFlagsString = bundle.getStringArray("disabledFlags");
|
||||
this.enabled = disabledFlagsString.length == 0;
|
||||
|
||||
for (final String flag : disabledFlagsString) {
|
||||
if (flag.equals("userDisabled")) {
|
||||
disabledFlags |= DisabledFlags.USER_DISABLED;
|
||||
} else if (flag.equals("blocklistDisabled")) {
|
||||
disabledFlags |= DisabledFlags.BLOCKLIST_DISABLED;
|
||||
} else {
|
||||
Log.e(LOGTAG, "Unrecognized disabledFlag state: " + flag);
|
||||
}
|
||||
}
|
||||
this.disabledFlags = disabledFlags;
|
||||
|
||||
if (bundle.containsKey("icons")) {
|
||||
icon = new Icon(bundle.getBundle("icons"));
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.mozilla.geckoview;
|
||||
|
||||
import android.support.annotation.AnyThread;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
|
@ -13,6 +14,8 @@ import org.mozilla.gecko.util.BundleEventListener;
|
|||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -411,12 +414,48 @@ public class WebExtensionController {
|
|||
return result;
|
||||
}
|
||||
|
||||
// TODO: Bug 1599585 make public
|
||||
GeckoResult<WebExtension> enable(final WebExtension extension) {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({ EnableSource.USER })
|
||||
@interface EnableSources {}
|
||||
|
||||
/** Contains the possible values for the <code>source</code> parameter in {@link #enable} and
|
||||
* {@link #disable}. */
|
||||
public static class EnableSource {
|
||||
/** Action has been requested by the user. */
|
||||
public final static int USER = 1;
|
||||
|
||||
// TODO: Bug 1604222
|
||||
/** Action requested by the app itself, e.g. to disable an extension that is
|
||||
* not supported in this version of the app. */
|
||||
final static int APP = 2;
|
||||
|
||||
static String toString(final @EnableSources int flag) {
|
||||
if (flag == USER) {
|
||||
return "user";
|
||||
} else {
|
||||
throw new IllegalArgumentException("Value provided in flags is not valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable an extension that has been disabled. If the extension is already enabled, this
|
||||
* method has no effect.
|
||||
*
|
||||
* @param extension The {@link WebExtension} to be enabled.
|
||||
* @param source The agent that initiated this action, e.g. if the action has been initiated
|
||||
* by the user,use {@link EnableSource#USER}.
|
||||
* @return the new {@link WebExtension} instance, updated to reflect the enablement.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public GeckoResult<WebExtension> enable(final @NonNull WebExtension extension,
|
||||
final @EnableSources int source) {
|
||||
final WebExtensionResult result = new WebExtensionResult("extension");
|
||||
|
||||
final GeckoBundle bundle = new GeckoBundle(1);
|
||||
final GeckoBundle bundle = new GeckoBundle(2);
|
||||
bundle.putString("webExtensionId", extension.id);
|
||||
bundle.putString("source", EnableSource.toString(source));
|
||||
|
||||
EventDispatcher.getInstance().dispatch("GeckoView:WebExtension:Enable",
|
||||
bundle, result);
|
||||
|
@ -427,12 +466,24 @@ public class WebExtensionController {
|
|||
});
|
||||
}
|
||||
|
||||
// TODO: Bug 1599585 make public
|
||||
GeckoResult<WebExtension> disable(final WebExtension extension) {
|
||||
/**
|
||||
* Disable an extension that is enabled. If the extension is already disabled, this
|
||||
* method has no effect.
|
||||
*
|
||||
* @param extension The {@link WebExtension} to be disabled.
|
||||
* @param source The agent that initiated this action, e.g. if the action has been initiated
|
||||
* by the user, use {@link EnableSource#USER}.
|
||||
* @return the new {@link WebExtension} instance, updated to reflect the disablement.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public GeckoResult<WebExtension> disable(final @NonNull WebExtension extension,
|
||||
final @EnableSources int source) {
|
||||
final WebExtensionResult result = new WebExtensionResult("extension");
|
||||
|
||||
final GeckoBundle bundle = new GeckoBundle(1);
|
||||
final GeckoBundle bundle = new GeckoBundle(2);
|
||||
bundle.putString("webExtensionId", extension.id);
|
||||
bundle.putString("source", EnableSource.toString(source));
|
||||
|
||||
EventDispatcher.getInstance().dispatch("GeckoView:WebExtension:Disable",
|
||||
bundle, result);
|
||||
|
|
|
@ -13,6 +13,14 @@ exclude: true
|
|||
|
||||
⚠️ breaking change
|
||||
|
||||
## v74
|
||||
- Added [`WebExtensionController.enable`][74.1] and [`disable`][74.2] to
|
||||
enable and disable extensions.
|
||||
([bug 1599585]({{bugzilla}}1599585))
|
||||
|
||||
[74.1]: {{javadoc_uri}}/WebExtensionController.html#enable-org.mozilla.geckoview.WebExtension-int-
|
||||
[74.2]: {{javadoc_uri}}/WebExtensionController.html#disable-org.mozilla.geckoview.WebExtension-int-
|
||||
|
||||
## v73
|
||||
- Added [`WebExtensionController.install`][73.1] and [`uninstall`][73.2] to
|
||||
manage installed extensions
|
||||
|
@ -522,4 +530,4 @@ exclude: true
|
|||
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
|
||||
[65.25]: {{javadoc_uri}}/GeckoResult.html
|
||||
|
||||
[api-version]: 2a944df46a5560f6b45f421536fd3051f9c32885
|
||||
[api-version]: 45f21fe6c3c30f903b65a573540901e8f45affca
|
||||
|
|
|
@ -252,7 +252,7 @@ function exportExtension(aAddon, aPermissions, aSourceURI) {
|
|||
optionsBrowserStyle,
|
||||
isRecommended,
|
||||
blocklistState,
|
||||
isActive,
|
||||
userDisabled,
|
||||
isBuiltin,
|
||||
id,
|
||||
} = aAddon;
|
||||
|
@ -265,15 +265,22 @@ function exportExtension(aAddon, aPermissions, aSourceURI) {
|
|||
}
|
||||
const openOptionsPageInTab =
|
||||
optionsBrowserStyle === AddonManager.OPTIONS_TYPE_TAB;
|
||||
const disabledFlags = [];
|
||||
if (userDisabled) {
|
||||
disabledFlags.push("userDisabled");
|
||||
}
|
||||
if (blocklistState !== Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
|
||||
disabledFlags.push("blocklistDisabled");
|
||||
}
|
||||
return {
|
||||
webExtensionId: id,
|
||||
locationURI: aSourceURI != null ? aSourceURI.spec : "",
|
||||
isEnabled: isActive,
|
||||
isBuiltIn: isBuiltin,
|
||||
metaData: {
|
||||
permissions: aPermissions ? aPermissions.permissions : [],
|
||||
origins: aPermissions ? aPermissions.origins : [],
|
||||
description,
|
||||
disabledFlags,
|
||||
version,
|
||||
creatorName,
|
||||
creatorURL,
|
||||
|
@ -495,6 +502,30 @@ var GeckoViewWebExtension = {
|
|||
}
|
||||
},
|
||||
|
||||
async enableWebExtension(aId, aSource) {
|
||||
const extension = await this.extensionById(aId);
|
||||
if (aSource === "user") {
|
||||
extension.enable();
|
||||
}
|
||||
return exportExtension(
|
||||
extension,
|
||||
extension.userPermissions,
|
||||
/* aSourceURI */ null
|
||||
);
|
||||
},
|
||||
|
||||
async disableWebExtension(aId, aSource) {
|
||||
const extension = await this.extensionById(aId);
|
||||
if (aSource === "user") {
|
||||
extension.disable();
|
||||
}
|
||||
return exportExtension(
|
||||
extension,
|
||||
extension.userPermissions,
|
||||
/* aSourceURI */ null
|
||||
);
|
||||
},
|
||||
|
||||
async onEvent(aEvent, aData, aCallback) {
|
||||
debug`onEvent ${aEvent} ${aData}`;
|
||||
|
||||
|
@ -629,14 +660,38 @@ var GeckoViewWebExtension = {
|
|||
}
|
||||
|
||||
case "GeckoView:WebExtension:Enable": {
|
||||
// TODO
|
||||
aCallback.onError(`Not implemented`);
|
||||
try {
|
||||
const { source, webExtensionId } = aData;
|
||||
if (source !== "user") {
|
||||
throw new Error("Illegal source parameter");
|
||||
}
|
||||
const extension = await this.enableWebExtension(
|
||||
webExtensionId,
|
||||
source
|
||||
);
|
||||
aCallback.onSuccess({ extension });
|
||||
} catch (ex) {
|
||||
debug`Failed enable ${ex}`;
|
||||
aCallback.onError(`Unexpected error: ${ex}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "GeckoView:WebExtension:Disable": {
|
||||
// TODO
|
||||
aCallback.onError(`Not implemented`);
|
||||
try {
|
||||
const { source, webExtensionId } = aData;
|
||||
if (source !== "user") {
|
||||
throw new Error("Illegal source parameter");
|
||||
}
|
||||
const extension = await this.disableWebExtension(
|
||||
webExtensionId,
|
||||
source
|
||||
);
|
||||
aCallback.onSuccess({ extension });
|
||||
} catch (ex) {
|
||||
debug`Failed disable ${ex}`;
|
||||
aCallback.onError(`Unexpected error: ${ex}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче