Commit 60977ffe authored by Luca Greco's avatar Luca Greco
Browse files

Bug 1748529 - Allow developer to forcefully terminate non-persistent...

Bug 1748529 - Allow developer to forcefully terminate non-persistent background script from about:debugging. r=jdescottes,mixedpuppy,fluent-reviewers,devtools-backward-compat-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D140379
parent 0d9fb502
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ const {
  TEMPORARY_EXTENSION_RELOAD_FAILURE,
  TEMPORARY_EXTENSION_RELOAD_START,
  TEMPORARY_EXTENSION_RELOAD_SUCCESS,
  TERMINATE_EXTENSION_BGSCRIPT_FAILURE,
  TERMINATE_EXTENSION_BGSCRIPT_SUCCESS,
  TERMINATE_EXTENSION_BGSCRIPT_START,
  RUNTIMES,
} = require("devtools/client/aboutdebugging/src/constants");

@@ -159,6 +162,22 @@ function removeTemporaryExtension(id) {
  };
}

function terminateExtensionBackgroundScript(id) {
  return async ({ dispatch, getState }) => {
    dispatch({ type: TERMINATE_EXTENSION_BGSCRIPT_START, id });
    const clientWrapper = getCurrentClient(getState().runtimes);

    try {
      const addonTargetFront = await clientWrapper.getAddon({ id });
      await addonTargetFront.terminateBackgroundScript();
      dispatch({ type: TERMINATE_EXTENSION_BGSCRIPT_SUCCESS, id });
    } catch (e) {
      const error = typeof e === "string" ? new Error(e) : e;
      dispatch({ type: TERMINATE_EXTENSION_BGSCRIPT_FAILURE, id, error });
    }
  };
}

function requestTabs() {
  return async ({ dispatch, getState }) => {
    dispatch({ type: REQUEST_TABS_START });
@@ -311,5 +330,6 @@ module.exports = {
  requestProcesses,
  requestWorkers,
  startServiceWorker,
  terminateExtensionBackgroundScript,
  unregisterServiceWorker,
};
+59 −0
Original line number Diff line number Diff line
@@ -43,6 +43,11 @@ class TemporaryExtensionAdditionalActions extends PureComponent {
    dispatch(Actions.reloadTemporaryExtension(target.id));
  }

  terminateBackgroundScript() {
    const { dispatch, target } = this.props;
    dispatch(Actions.terminateExtensionBackgroundScript(target.id));
  }

  remove() {
    const { dispatch, target } = this.props;
    dispatch(Actions.removeTemporaryExtension(target.id));
@@ -75,6 +80,58 @@ class TemporaryExtensionAdditionalActions extends PureComponent {
    );
  }

  renderTerminateBackgroundScriptError() {
    const { lastTerminateBackgroundScriptError } = this.props.target.details;

    if (!lastTerminateBackgroundScriptError) {
      return null;
    }

    return Message(
      {
        className: "qa-temporary-extension-terminate-backgroundscript-error",
        level: MESSAGE_LEVEL.ERROR,
        key: "terminate-backgroundscript-error",
      },
      DetailsLog(
        {
          type: MESSAGE_LEVEL.ERROR,
        },
        dom.p(
          {
            className: "technical-text",
          },
          lastTerminateBackgroundScriptError
        )
      )
    );
  }

  renderTerminateBackgroundScriptButton() {
    const { persistentBackgroundScript } = this.props.target.details;

    // For extensions with a non persistent background script
    // also include a "terminate background script" action.
    if (persistentBackgroundScript !== false) {
      return null;
    }

    return Localized(
      {
        id: "about-debugging-tmp-extension-terminate-bgscript-button",
      },
      dom.button(
        {
          className:
            "default-button default-button--micro " +
            "qa-temporary-extension-terminate-bgscript-button",
          onClick: e => this.terminateBackgroundScript(),
        },
        "Terminate Background Script"
      )
    );
  }

  render() {
    return [
      dom.div(
@@ -82,6 +139,7 @@ class TemporaryExtensionAdditionalActions extends PureComponent {
          className: "toolbar toolbar--right-align",
          key: "actions",
        },
        this.renderTerminateBackgroundScriptButton(),
        Localized(
          {
            id: "about-debugging-tmp-extension-reload-button",
@@ -112,6 +170,7 @@ class TemporaryExtensionAdditionalActions extends PureComponent {
        )
      ),
      this.renderReloadError(),
      this.renderTerminateBackgroundScriptError(),
    ];
  }
}
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ const actionTypes = {
  TEMPORARY_EXTENSION_RELOAD_FAILURE: "TEMPORARY_EXTENSION_RELOAD_FAILURE",
  TEMPORARY_EXTENSION_RELOAD_START: "TEMPORARY_EXTENSION_RELOAD_START",
  TEMPORARY_EXTENSION_RELOAD_SUCCESS: "TEMPORARY_EXTENSION_RELOAD_SUCCESS",
  TERMINATE_EXTENSION_BGSCRIPT_FAILURE: "TERMINATE_EXTENSION_BGSCRIPT_FAILURE",
  TERMINATE_EXTENSION_BGSCRIPT_START: "TERMINATE_EXTENSION_BGSCRIPT_START",
  TERMINATE_EXTENSION_BGSCRIPT_SUCCESS: "TERMINATE_EXTENSION_BGSCRIPT_SUCCESS",
  THIS_FIREFOX_RUNTIME_CREATED: "THIS_FIREFOX_RUNTIME_CREATED",
  UNWATCH_RUNTIME_FAILURE: "UNWATCH_RUNTIME_FAILURE",
  UNWATCH_RUNTIME_START: "UNWATCH_RUNTIME_START",
+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ function toComponentData(extensions) {
      id,
      manifestURL,
      name,
      persistentBackgroundScript,
      warnings,
    } = extension;
    const icon =
@@ -70,6 +71,7 @@ function toComponentData(extensions) {
        actor,
        location,
        manifestURL,
        persistentBackgroundScript,
        uuid,
        warnings: warnings || [],
      },
+50 −2
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@ const {
  REQUEST_WORKERS_SUCCESS,
  TEMPORARY_EXTENSION_RELOAD_FAILURE,
  TEMPORARY_EXTENSION_RELOAD_START,
  TERMINATE_EXTENSION_BGSCRIPT_FAILURE,
  TERMINATE_EXTENSION_BGSCRIPT_START,
  UNWATCH_RUNTIME_SUCCESS,
} = require("devtools/client/aboutdebugging/src/constants");

@@ -26,16 +28,33 @@ function DebugTargetsState() {
  };
}

function updateTemporaryExtension(state, id, updatedDetails) {
  return state.temporaryExtensions.map(extension => {
function updateExtensionDetails(extensions, id, updatedDetails) {
  // extensions is meant to be either state.installExtensions or state.temporaryExtensions.
  return extensions.map(extension => {
    if (extension.id === id) {
      extension = Object.assign({}, extension);

      extension.details = Object.assign({}, extension.details, updatedDetails);
    }
    return extension;
  });
}

function updateTemporaryExtension(state, id, updatedDetails) {
  return updateExtensionDetails(state.temporaryExtensions, id, updatedDetails);
}

function updateInstalledExtension(state, id, updatedDetails) {
  return updateExtensionDetails(state.installedExtensions, id, updatedDetails);
}

function updateExtension(state, id, updatedDetails) {
  return {
    installedExtensions: updateInstalledExtension(state, id, updatedDetails),
    temporaryExtensions: updateTemporaryExtension(state, id, updatedDetails),
  };
}

function debugTargetsReducer(state = DebugTargetsState(), action) {
  switch (action.type) {
    case UNWATCH_RUNTIME_SUCCESS: {
@@ -78,6 +97,35 @@ function debugTargetsReducer(state = DebugTargetsState(), action) {
      });
      return Object.assign({}, state, { temporaryExtensions });
    }
    case TERMINATE_EXTENSION_BGSCRIPT_START: {
      const { id } = action;
      const { installedExtensions, temporaryExtensions } = updateExtension(
        state,
        id,
        {
          // Clear the last error if one was still set.
          lastTerminateBackgroundScriptError: null,
        }
      );
      return Object.assign({}, state, {
        installedExtensions,
        temporaryExtensions,
      });
    }
    case TERMINATE_EXTENSION_BGSCRIPT_FAILURE: {
      const { id, error } = action;
      const { installedExtensions, temporaryExtensions } = updateExtension(
        state,
        id,
        {
          lastTerminateBackgroundScriptError: error.message,
        }
      );
      return Object.assign({}, state, {
        installedExtensions,
        temporaryExtensions,
      });
    }

    default:
      return state;
Loading