зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1599806 - remove setupInParent from accessibility actor and split up child/parent functionality into two separate actors. r=ochameau
Differential Revision: https://phabricator.services.mozilla.com/D58807 --HG-- rename : devtools/server/actors/accessibility/accessibility-parent.js => devtools/server/actors/accessibility/parent-accessibility.js extra : moz-landing-system : lando
This commit is contained in:
Родитель
aabab512b9
Коммит
cbbc2cdd24
|
@ -9,6 +9,11 @@ const {
|
|||
} = require("devtools/shared/constants");
|
||||
const { FILTERS } = require("devtools/client/accessibility/constants");
|
||||
|
||||
const PARENT_ACCESSIBILITY_EVENTS = [
|
||||
"can-be-disabled-change",
|
||||
"can-be-enabled-change",
|
||||
];
|
||||
|
||||
/**
|
||||
* Component responsible for tracking all Accessibility fronts in parent and
|
||||
* content processes.
|
||||
|
@ -100,12 +105,34 @@ class AccessibilityProxy {
|
|||
this.accessibleWalkerFront.off("picker-accessible-canceled", onCanceled);
|
||||
}
|
||||
|
||||
disableAccessibility() {
|
||||
return this.accessibilityFront.disable();
|
||||
async disableAccessibility() {
|
||||
// Accessibility service is shut down using the parent accessibility front.
|
||||
// That, in turn, shuts down accessibility service in all content processes.
|
||||
// We need to wait until that happens to be sure platform accessibility is
|
||||
// fully disabled.
|
||||
// TODO: Remove this after Firefox 75 and use parentAccessibilityFront.
|
||||
if (this.parentAccessibilityFront) {
|
||||
const disabled = this.accessibilityFront.once("shutdown");
|
||||
await this.parentAccessibilityFront.disable();
|
||||
await disabled;
|
||||
} else {
|
||||
await this.accessibilityFront.disable();
|
||||
}
|
||||
}
|
||||
|
||||
enableAccessibility() {
|
||||
return this.accessibilityFront.enable();
|
||||
async enableAccessibility() {
|
||||
// Accessibility service is initialized using the parent accessibility
|
||||
// front. That, in turn, initializes accessibility service in all content
|
||||
// processes. We need to wait until that happens to be sure platform
|
||||
// accessibility is fully enabled.
|
||||
// TODO: Remove this after Firefox 75 and use parentAccessibilityFront.
|
||||
if (this.parentAccessibilityFront) {
|
||||
const enabled = this.accessibilityFront.once("init");
|
||||
await this.parentAccessibilityFront.enable();
|
||||
await enabled;
|
||||
} else {
|
||||
await this.accessibilityFront.enable();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,7 +160,9 @@ class AccessibilityProxy {
|
|||
}
|
||||
|
||||
async resetAccessiblity() {
|
||||
const { enabled, canBeDisabled, canBeEnabled } = this.accessibilityFront;
|
||||
const { enabled } = this.accessibilityFront;
|
||||
const { canBeEnabled, canBeDisabled } =
|
||||
this.parentAccessibilityFront || this.accessibilityFront;
|
||||
return { enabled, canBeDisabled, canBeEnabled };
|
||||
}
|
||||
|
||||
|
@ -152,8 +181,14 @@ class AccessibilityProxy {
|
|||
startListeningForLifecycleEvents(eventMap) {
|
||||
for (let [type, listeners] of Object.entries(eventMap)) {
|
||||
listeners = Array.isArray(listeners) ? listeners : [listeners];
|
||||
const accessibilityFront =
|
||||
// TODO: Remove parentAccessibilityFront check after Firefox 75.
|
||||
this.parentAccessibilityFront &&
|
||||
PARENT_ACCESSIBILITY_EVENTS.includes(type)
|
||||
? this.parentAccessibilityFront
|
||||
: this.accessibilityFront;
|
||||
for (const listener of listeners) {
|
||||
this.accessibilityFront.on(type, listener);
|
||||
accessibilityFront.on(type, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,24 +196,39 @@ class AccessibilityProxy {
|
|||
stopListeningForLifecycleEvents(eventMap) {
|
||||
for (let [type, listeners] of Object.entries(eventMap)) {
|
||||
listeners = Array.isArray(listeners) ? listeners : [listeners];
|
||||
// TODO: Remove parentAccessibilityFront check after Firefox 75.
|
||||
const accessibilityFront =
|
||||
this.parentAccessibilityFront &&
|
||||
PARENT_ACCESSIBILITY_EVENTS.includes(type)
|
||||
? this.parentAccessibilityFront
|
||||
: this.accessibilityFront;
|
||||
for (const listener of listeners) {
|
||||
this.accessibilityFront.off(type, listener);
|
||||
accessibilityFront.off(type, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async ensureReady() {
|
||||
const { mainRoot } = this.target.client;
|
||||
if (await mainRoot.hasActor("parentAccessibility")) {
|
||||
this.parentAccessibilityFront = await mainRoot.getFront(
|
||||
"parentaccessibility"
|
||||
);
|
||||
}
|
||||
|
||||
this.accessibleWalkerFront = this.accessibilityFront.accessibleWalkerFront;
|
||||
this.simulatorFront = this.accessibilityFront.simulatorFront;
|
||||
if (this.simulatorFront) {
|
||||
this.simulate = types => this.simulatorFront.simulate({ types });
|
||||
}
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
try {
|
||||
this.accessibilityFront = await this.target.getFront("accessibility");
|
||||
// Finalize accessibility front initialization. See accessibility front
|
||||
// bootstrap method description.
|
||||
await this.accessibilityFront.bootstrap();
|
||||
this.accessibleWalkerFront = this.accessibilityFront.accessibleWalkerFront;
|
||||
this.simulatorFront = this.accessibilityFront.simulatorFront;
|
||||
if (this.simulatorFront) {
|
||||
this.simulate = types => this.simulatorFront.simulate({ types });
|
||||
}
|
||||
|
||||
this.supports = {};
|
||||
// To add a check for backward compatibility add something similar to the
|
||||
// example below:
|
||||
|
@ -196,6 +246,7 @@ class AccessibilityProxy {
|
|||
|
||||
destroy() {
|
||||
this.accessibilityFront = null;
|
||||
this.parentAccessibilityFront = null;
|
||||
this.accessibleWalkerFront = null;
|
||||
this.simulatorFront = null;
|
||||
this.simulate = null;
|
||||
|
|
|
@ -90,6 +90,7 @@ AccessibilityPanel.prototype = {
|
|||
this.shouldRefresh = true;
|
||||
|
||||
await this.startup.initAccessibility();
|
||||
await this.accessibilityProxy.ensureReady();
|
||||
this.picker = new Picker(this);
|
||||
this.fluentBundles = await this.createFluentBundles();
|
||||
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { DevToolsServer } = require("devtools/server/devtools-server");
|
||||
const Services = require("Services");
|
||||
const { Actor, ActorClassWithSpec } = require("devtools/shared/protocol");
|
||||
const defer = require("devtools/shared/defer");
|
||||
const { accessibilitySpec } = require("devtools/shared/specs/accessibility");
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
|
@ -22,7 +20,6 @@ loader.lazyRequireGetter(
|
|||
"devtools/server/actors/accessibility/simulator",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(this, "events", "devtools/shared/event-emitter");
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"isWebRenderEnabled",
|
||||
|
@ -30,189 +27,35 @@ loader.lazyRequireGetter(
|
|||
true
|
||||
);
|
||||
|
||||
const PREF_ACCESSIBILITY_FORCE_DISABLED = "accessibility.force_disabled";
|
||||
|
||||
/**
|
||||
* The AccessibilityActor is a top level container actor that initializes
|
||||
* accessible walker and is the top-most point of interaction for accessibility
|
||||
* tools UI.
|
||||
* tools UI for a top level content process.
|
||||
*/
|
||||
const AccessibilityActor = ActorClassWithSpec(accessibilitySpec, {
|
||||
initialize(conn, targetActor) {
|
||||
Actor.prototype.initialize.call(this, conn);
|
||||
|
||||
this.initializedDeferred = defer();
|
||||
|
||||
if (DevToolsServer.isInChildProcess) {
|
||||
this._msgName = `debug:${this.conn.prefix}accessibility`;
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
this.conn.setupInParent({
|
||||
module: "devtools/server/actors/accessibility/accessibility-parent",
|
||||
setupParent: "setupParentProcess",
|
||||
});
|
||||
|
||||
this.onMessage = this.onMessage.bind(this);
|
||||
this.messageManager.addMessageListener(
|
||||
`${this._msgName}:event`,
|
||||
this.onMessage
|
||||
);
|
||||
} else {
|
||||
this.userPref = Services.prefs.getIntPref(
|
||||
PREF_ACCESSIBILITY_FORCE_DISABLED
|
||||
);
|
||||
Services.obs.addObserver(this, "a11y-consumers-changed");
|
||||
Services.prefs.addObserver(PREF_ACCESSIBILITY_FORCE_DISABLED, this);
|
||||
this.initializedDeferred.resolve();
|
||||
}
|
||||
|
||||
// This event is fired when accessibility service is initialized or shut
|
||||
// down. "init" and "shutdown" events are only relayed when the enabled
|
||||
// state matches the event (e.g. the event came from the same process as
|
||||
// the actor).
|
||||
Services.obs.addObserver(this, "a11y-init-or-shutdown");
|
||||
this.targetActor = targetActor;
|
||||
},
|
||||
|
||||
bootstrap() {
|
||||
return this.initializedDeferred.promise.then(() => ({
|
||||
return {
|
||||
enabled: this.enabled,
|
||||
canBeEnabled: this.canBeEnabled,
|
||||
canBeDisabled: this.canBeDisabled,
|
||||
}));
|
||||
};
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
return Services.appinfo.accessibilityEnabled;
|
||||
},
|
||||
|
||||
get canBeEnabled() {
|
||||
if (DevToolsServer.isInChildProcess) {
|
||||
return this._canBeEnabled;
|
||||
}
|
||||
|
||||
return Services.prefs.getIntPref(PREF_ACCESSIBILITY_FORCE_DISABLED) < 1;
|
||||
},
|
||||
|
||||
get canBeDisabled() {
|
||||
if (DevToolsServer.isInChildProcess) {
|
||||
return this._canBeDisabled;
|
||||
} else if (!this.enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const { PlatformAPI } = JSON.parse(this.walker.a11yService.getConsumers());
|
||||
return !PlatformAPI;
|
||||
},
|
||||
|
||||
/**
|
||||
* Getter for a message manager that corresponds to a current tab. It is onyl
|
||||
* used if the AccessibilityActor runs in the child process.
|
||||
*
|
||||
* @return {Object}
|
||||
* Message manager that corresponds to the current content tab.
|
||||
*/
|
||||
get messageManager() {
|
||||
if (!DevToolsServer.isInChildProcess) {
|
||||
throw new Error(
|
||||
"Message manager should only be used when actor is in child process."
|
||||
);
|
||||
}
|
||||
|
||||
return this.conn.parentMessageManager;
|
||||
},
|
||||
|
||||
onMessage(msg) {
|
||||
const { topic, data } = msg.data;
|
||||
|
||||
switch (topic) {
|
||||
case "initialized":
|
||||
this._canBeEnabled = data.canBeEnabled;
|
||||
this._canBeDisabled = data.canBeDisabled;
|
||||
|
||||
// Sometimes when the tool is reopened content process accessibility service is
|
||||
// not shut down yet because GC did not run in that process (though it did in
|
||||
// parent process and the service was shut down there). We need to sync the two
|
||||
// services if possible.
|
||||
if (!data.enabled && this.enabled && data.canBeEnabled) {
|
||||
this.messageManager.sendAsyncMessage(this._msgName, {
|
||||
action: "enable",
|
||||
});
|
||||
}
|
||||
|
||||
this.initializedDeferred.resolve();
|
||||
break;
|
||||
case "can-be-disabled-change":
|
||||
this._canBeDisabled = data;
|
||||
events.emit(this, "can-be-disabled-change", this.canBeDisabled);
|
||||
break;
|
||||
|
||||
case "can-be-enabled-change":
|
||||
this._canBeEnabled = data;
|
||||
events.emit(this, "can-be-enabled-change", this.canBeEnabled);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable acessibility service in the given process.
|
||||
*/
|
||||
async enable() {
|
||||
if (this.enabled || !this.canBeEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const initPromise = this.once("init");
|
||||
|
||||
if (DevToolsServer.isInChildProcess) {
|
||||
this.messageManager.sendAsyncMessage(this._msgName, { action: "enable" });
|
||||
} else {
|
||||
// This executes accessibility service lazy getter and adds accessible
|
||||
// events observer.
|
||||
this.walker.a11yService;
|
||||
}
|
||||
|
||||
await initPromise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable acessibility service in the given process.
|
||||
*/
|
||||
async disable() {
|
||||
if (!this.enabled || !this.canBeDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.disabling = true;
|
||||
const shutdownPromise = this.once("shutdown");
|
||||
if (DevToolsServer.isInChildProcess) {
|
||||
this.messageManager.sendAsyncMessage(this._msgName, {
|
||||
action: "disable",
|
||||
});
|
||||
} else {
|
||||
// Set PREF_ACCESSIBILITY_FORCE_DISABLED to 1 to force disable
|
||||
// accessibility service. This is the only way to guarantee an immediate
|
||||
// accessibility service shutdown in all processes. This also prevents
|
||||
// accessibility service from starting up in the future.
|
||||
//
|
||||
// TODO: Introduce a shutdown method that is exposed via XPCOM on
|
||||
// accessibility service.
|
||||
Services.prefs.setIntPref(PREF_ACCESSIBILITY_FORCE_DISABLED, 1);
|
||||
// Set PREF_ACCESSIBILITY_FORCE_DISABLED back to previous default or user
|
||||
// set value. This will not start accessibility service until the user
|
||||
// activates it again. It simply ensures that accessibility service can
|
||||
// start again (when value is below 1).
|
||||
Services.prefs.setIntPref(
|
||||
PREF_ACCESSIBILITY_FORCE_DISABLED,
|
||||
this.userPref
|
||||
);
|
||||
}
|
||||
|
||||
await shutdownPromise;
|
||||
delete this.disabling;
|
||||
},
|
||||
|
||||
/**
|
||||
* Observe Accessibility service init and shutdown events. It relays these
|
||||
* events to AccessibilityFront iff the event is fired for the a11y service
|
||||
* events to AccessibilityFront if the event is fired for the a11y service
|
||||
* that lives in the same process.
|
||||
*
|
||||
* @param {null} subject
|
||||
|
@ -223,41 +66,15 @@ const AccessibilityActor = ActorClassWithSpec(accessibilitySpec, {
|
|||
* "0" corresponds to shutdown and "1" to init.
|
||||
*/
|
||||
observe(subject, topic, data) {
|
||||
if (topic === "a11y-init-or-shutdown") {
|
||||
// This event is fired when accessibility service is initialized or shut
|
||||
// down. "init" and "shutdown" events are only relayed when the enabled
|
||||
// state matches the event (e.g. the event came from the same process as
|
||||
// the actor).
|
||||
const enabled = data === "1";
|
||||
if (enabled && this.enabled) {
|
||||
events.emit(this, "init");
|
||||
this.emit("init");
|
||||
} else if (!enabled && !this.enabled) {
|
||||
if (this.walker) {
|
||||
this.walker.reset();
|
||||
}
|
||||
|
||||
events.emit(this, "shutdown");
|
||||
}
|
||||
} else if (topic === "a11y-consumers-changed") {
|
||||
// This event is fired when accessibility service consumers change. There
|
||||
// are 3 possible consumers of a11y service: XPCOM, PlatformAPI (e.g.
|
||||
// screen readers) and MainProcess. PlatformAPI consumer can only be set
|
||||
// in parent process, and MainProcess consumer can only be set in child
|
||||
// process. We only care about PlatformAPI consumer changes because when
|
||||
// set, we can no longer disable accessibility service.
|
||||
const { PlatformAPI } = JSON.parse(data);
|
||||
events.emit(this, "can-be-disabled-change", !PlatformAPI);
|
||||
} else if (
|
||||
!this.disabling &&
|
||||
topic === "nsPref:changed" &&
|
||||
data === PREF_ACCESSIBILITY_FORCE_DISABLED
|
||||
) {
|
||||
// PREF_ACCESSIBILITY_FORCE_DISABLED preference change event. When set to
|
||||
// >=1, it means that the user wants to disable accessibility service and
|
||||
// prevent it from starting in the future. Note: we also check
|
||||
// this.disabling state when handling this pref change because this is how
|
||||
// we disable the accessibility inspector itself.
|
||||
events.emit(this, "can-be-enabled-change", this.canBeEnabled);
|
||||
this.emit("shutdown");
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -277,9 +94,10 @@ const AccessibilityActor = ActorClassWithSpec(accessibilitySpec, {
|
|||
|
||||
/**
|
||||
* Get or create Simulator actor, managed by AccessibilityActor,
|
||||
* only if webrender is enabled. Simulator applies color filters on an entire viewport.
|
||||
* This needs to be done using webrender and not an SVG <feColorMatrix> since it is
|
||||
* accelerated and scrolling with filter applied needs to be smooth (Bug1431466).
|
||||
* only if webrender is enabled. Simulator applies color filters on an entire
|
||||
* viewport. This needs to be done using webrender and not an SVG
|
||||
* <feColorMatrix> since it is accelerated and scrolling with filter applied
|
||||
* needs to be smooth (Bug1431466).
|
||||
*
|
||||
* @return {Object|null}
|
||||
* SimulatorActor for the current tab.
|
||||
|
@ -299,35 +117,14 @@ const AccessibilityActor = ActorClassWithSpec(accessibilitySpec, {
|
|||
},
|
||||
|
||||
/**
|
||||
* Destroy accessibility service actor. This method also shutsdown
|
||||
* accessibility service if possible.
|
||||
* Destroy accessibility actor. This method also shutsdown accessibility
|
||||
* service if possible.
|
||||
*/
|
||||
async destroy() {
|
||||
if (this.destroyed) {
|
||||
await this.destroyed;
|
||||
return;
|
||||
}
|
||||
|
||||
let resolver;
|
||||
this.destroyed = new Promise(resolve => {
|
||||
resolver = resolve;
|
||||
});
|
||||
|
||||
Services.obs.removeObserver(this, "a11y-init-or-shutdown");
|
||||
if (DevToolsServer.isInChildProcess) {
|
||||
this.messageManager.removeMessageListener(
|
||||
`${this._msgName}:event`,
|
||||
this.onMessage
|
||||
);
|
||||
} else {
|
||||
Services.obs.removeObserver(this, "a11y-consumers-changed");
|
||||
Services.prefs.removeObserver(PREF_ACCESSIBILITY_FORCE_DISABLED, this);
|
||||
}
|
||||
|
||||
Actor.prototype.destroy.call(this);
|
||||
Services.obs.removeObserver(this, "a11y-init-or-shutdown");
|
||||
this.walker = null;
|
||||
this.targetActor = null;
|
||||
resolver();
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ DIRS += [
|
|||
]
|
||||
|
||||
DevToolsModules(
|
||||
'accessibility-parent.js',
|
||||
'accessibility.js',
|
||||
'accessible.js',
|
||||
'constants.js',
|
||||
'parent-accessibility.js',
|
||||
'simulator.js',
|
||||
'walker.js',
|
||||
'worker.js',
|
||||
|
|
|
@ -6,26 +6,20 @@
|
|||
|
||||
const { Cc, Ci } = require("chrome");
|
||||
const Services = require("Services");
|
||||
const { Actor, ActorClassWithSpec } = require("devtools/shared/protocol");
|
||||
const {
|
||||
parentAccessibilitySpec,
|
||||
} = require("devtools/shared/specs/accessibility");
|
||||
|
||||
const PREF_ACCESSIBILITY_FORCE_DISABLED = "accessibility.force_disabled";
|
||||
|
||||
/**
|
||||
* A helper class that does all the work related to accessibility service
|
||||
* lifecycle (initialization, shutdown, consumer changes, etc) in parent
|
||||
* parent process. It is not guaranteed that the AccessibilityActor starts in
|
||||
* parent process and thus triggering these lifecycle functions directly is
|
||||
* extremely unreliable.
|
||||
*/
|
||||
class AccessibilityParent {
|
||||
constructor(mm, prefix) {
|
||||
this._msgName = `debug:${prefix}accessibility`;
|
||||
this.onAccessibilityMessage = this.onAccessibilityMessage.bind(this);
|
||||
this.setMessageManager(mm);
|
||||
const ParentAccessibilityActor = ActorClassWithSpec(parentAccessibilitySpec, {
|
||||
initialize(conn) {
|
||||
Actor.prototype.initialize.call(this, conn);
|
||||
|
||||
this.userPref = Services.prefs.getIntPref(
|
||||
PREF_ACCESSIBILITY_FORCE_DISABLED
|
||||
);
|
||||
Services.obs.addObserver(this, "a11y-consumers-changed");
|
||||
Services.prefs.addObserver(PREF_ACCESSIBILITY_FORCE_DISABLED, this);
|
||||
|
||||
if (this.enabled && !this.accService) {
|
||||
// Set a local reference to an accessibility service if accessibility was
|
||||
|
@ -36,65 +30,16 @@ class AccessibilityParent {
|
|||
);
|
||||
}
|
||||
|
||||
this.messageManager.sendAsyncMessage(`${this._msgName}:event`, {
|
||||
topic: "initialized",
|
||||
data: {
|
||||
enabled: this.enabled,
|
||||
Services.obs.addObserver(this, "a11y-consumers-changed");
|
||||
Services.prefs.addObserver(PREF_ACCESSIBILITY_FORCE_DISABLED, this);
|
||||
},
|
||||
|
||||
bootstrap() {
|
||||
return {
|
||||
canBeDisabled: this.canBeDisabled,
|
||||
canBeEnabled: this.canBeEnabled,
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up message manager listener to listen for messages coming from the
|
||||
* AccessibilityActor when it is instantiated in the child process.
|
||||
*
|
||||
* @param {Object} mm
|
||||
* Message manager that corresponds to the current content tab.
|
||||
*/
|
||||
setMessageManager(mm) {
|
||||
if (this.messageManager === mm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.messageManager) {
|
||||
// If the browser was swapped we need to reset the message manager.
|
||||
const oldMM = this.messageManager;
|
||||
oldMM.removeMessageListener(this._msgName, this.onAccessibilityMessage);
|
||||
}
|
||||
|
||||
this.messageManager = mm;
|
||||
if (mm) {
|
||||
mm.addMessageListener(this._msgName, this.onAccessibilityMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Content AccessibilityActor message listener.
|
||||
*
|
||||
* @param {String} msg
|
||||
* Name of the action to perform.
|
||||
*/
|
||||
onAccessibilityMessage(msg) {
|
||||
const { action } = msg.json;
|
||||
switch (action) {
|
||||
case "enable":
|
||||
this.enable();
|
||||
break;
|
||||
|
||||
case "disable":
|
||||
this.disable();
|
||||
break;
|
||||
|
||||
case "disconnect":
|
||||
this.destroy();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
observe(subject, topic, data) {
|
||||
if (topic === "a11y-consumers-changed") {
|
||||
|
@ -104,10 +49,7 @@ class AccessibilityParent {
|
|||
// about PlatformAPI consumer changes because when set, we can no longer
|
||||
// disable accessibility service.
|
||||
const { PlatformAPI } = JSON.parse(data);
|
||||
this.messageManager.sendAsyncMessage(`${this._msgName}:event`, {
|
||||
topic: "can-be-disabled-change",
|
||||
data: !PlatformAPI,
|
||||
});
|
||||
this.emit("can-be-disabled-change", !PlatformAPI);
|
||||
} else if (
|
||||
!this.disabling &&
|
||||
topic === "nsPref:changed" &&
|
||||
|
@ -118,12 +60,9 @@ class AccessibilityParent {
|
|||
// prevent it from starting in the future. Note: we also check
|
||||
// this.disabling state when handling this pref change because this is how
|
||||
// we disable the accessibility inspector itself.
|
||||
this.messageManager.sendAsyncMessage(`${this._msgName}:event`, {
|
||||
topic: "can-be-enabled-change",
|
||||
data: Services.prefs.getIntPref(PREF_ACCESSIBILITY_FORCE_DISABLED) < 1,
|
||||
});
|
||||
}
|
||||
this.emit("can-be-enabled-change", this.canBeEnabled);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A getter that indicates if accessibility service is enabled.
|
||||
|
@ -133,7 +72,7 @@ class AccessibilityParent {
|
|||
*/
|
||||
get enabled() {
|
||||
return Services.appinfo.accessibilityEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A getter that indicates if the accessibility service can be disabled.
|
||||
|
@ -151,7 +90,7 @@ class AccessibilityParent {
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A getter that indicates if the accessibility service can be enabled.
|
||||
|
@ -161,7 +100,7 @@ class AccessibilityParent {
|
|||
*/
|
||||
get canBeEnabled() {
|
||||
return Services.prefs.getIntPref(PREF_ACCESSIBILITY_FORCE_DISABLED) < 1;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable accessibility service (via XPCOM service).
|
||||
|
@ -174,7 +113,7 @@ class AccessibilityParent {
|
|||
this.accService = Cc["@mozilla.org/accessibilityService;1"].getService(
|
||||
Ci.nsIAccessibilityService
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Force disable accessibility service. This method removes the reference to
|
||||
|
@ -200,42 +139,18 @@ class AccessibilityParent {
|
|||
// start again (when value is below 1).
|
||||
Services.prefs.setIntPref(PREF_ACCESSIBILITY_FORCE_DISABLED, this.userPref);
|
||||
delete this.disabling;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy thie helper class, remove all listeners and if possible disable
|
||||
* accessibility service in the parent process.
|
||||
*/
|
||||
destroy() {
|
||||
Actor.prototype.destroy.call(this);
|
||||
Services.obs.removeObserver(this, "a11y-consumers-changed");
|
||||
Services.prefs.removeObserver(PREF_ACCESSIBILITY_FORCE_DISABLED, this);
|
||||
this.setMessageManager(null);
|
||||
this.accService = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup function that runs in parent process and setups AccessibleActor bits
|
||||
* that must always run in parent process.
|
||||
*
|
||||
* @param {Object} options.mm
|
||||
* Message manager that corresponds to the current content tab.
|
||||
* @param {String} options.prefix
|
||||
* Unique prefix for message manager messages.
|
||||
* @return {Object}
|
||||
* Defines event listeners for when client disconnects or browser gets
|
||||
* swapped.
|
||||
*/
|
||||
function setupParentProcess({ mm, prefix }) {
|
||||
let accessibility = new AccessibilityParent(mm, prefix);
|
||||
|
||||
return {
|
||||
onBrowserSwap: newMM => accessibility.setMessageManager(newMM),
|
||||
onDisconnected: () => {
|
||||
accessibility.destroy();
|
||||
accessibility = null;
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
exports.setupParentProcess = setupParentProcess;
|
||||
exports.ParentAccessibilityActor = ParentAccessibilityActor;
|
|
@ -156,6 +156,19 @@ const ActorRegistry = {
|
|||
constructor: "PerfActor",
|
||||
type: { global: true },
|
||||
});
|
||||
/**
|
||||
* Always register parent accessibility actor as a global module. This
|
||||
* actor is responsible for all top level accessibility actor functionality
|
||||
* that relies on the parent process.
|
||||
*/
|
||||
this.registerModule(
|
||||
"devtools/server/actors/accessibility/parent-accessibility",
|
||||
{
|
||||
prefix: "parentAccessibility",
|
||||
constructor: "ParentAccessibilityActor",
|
||||
type: { global: true },
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,6 +12,7 @@ const {
|
|||
accessibleSpec,
|
||||
accessibleWalkerSpec,
|
||||
accessibilitySpec,
|
||||
parentAccessibilitySpec,
|
||||
simulatorSpec,
|
||||
} = require("devtools/shared/specs/accessibility");
|
||||
const events = require("devtools/shared/event-emitter");
|
||||
|
@ -180,10 +181,14 @@ class AccessibilityFront extends FrontClassWithSpec(accessibilitySpec) {
|
|||
|
||||
this.before("init", this.init.bind(this));
|
||||
this.before("shutdown", this.shutdown.bind(this));
|
||||
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
this.before("can-be-enabled-change", this.canBeEnabled.bind(this));
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
this.before("can-be-disabled-change", this.canBeDisabled.bind(this));
|
||||
|
||||
// Attribute name from which to retrieve the actorID out of the target actor's form
|
||||
// Attribute name from which to retrieve the actorID out of the target
|
||||
// actor's form
|
||||
this.formAttributeName = "accessibilityActor";
|
||||
}
|
||||
|
||||
|
@ -200,6 +205,7 @@ class AccessibilityFront extends FrontClassWithSpec(accessibilitySpec) {
|
|||
async bootstrap() {
|
||||
this.accessibleWalkerFront = await super.getWalker();
|
||||
this.simulatorFront = await super.getSimulator();
|
||||
// TODO: Deprecated. Remove canBeEnabled and canBeDisabled after Fx75.
|
||||
({
|
||||
enabled: this.enabled,
|
||||
canBeEnabled: this.canBeEnabled,
|
||||
|
@ -215,6 +221,37 @@ class AccessibilityFront extends FrontClassWithSpec(accessibilitySpec) {
|
|||
this.enabled = false;
|
||||
}
|
||||
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
canBeEnabled(canBeEnabled) {
|
||||
this.canBeEnabled = canBeEnabled;
|
||||
}
|
||||
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
canBeDisabled(canBeDisabled) {
|
||||
this.canBeDisabled = canBeDisabled;
|
||||
}
|
||||
}
|
||||
|
||||
class ParentAccessibilityFront extends FrontClassWithSpec(
|
||||
parentAccessibilitySpec
|
||||
) {
|
||||
constructor(client, targetFront, parentFront) {
|
||||
super(client, targetFront, parentFront);
|
||||
this.before("can-be-enabled-change", this.canBeEnabled.bind(this));
|
||||
this.before("can-be-disabled-change", this.canBeDisabled.bind(this));
|
||||
|
||||
// Attribute name from which to retrieve the actorID out of the target
|
||||
// actor's form
|
||||
this.formAttributeName = "parentAccessibilityActor";
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
({
|
||||
canBeEnabled: this.canBeEnabled,
|
||||
canBeDisabled: this.canBeDisabled,
|
||||
} = await super.bootstrap());
|
||||
}
|
||||
|
||||
canBeEnabled(canBeEnabled) {
|
||||
this.canBeEnabled = canBeEnabled;
|
||||
}
|
||||
|
@ -232,5 +269,7 @@ exports.AccessibleWalkerFront = AccessibleWalkerFront;
|
|||
registerFront(AccessibleWalkerFront);
|
||||
exports.AccessibilityFront = AccessibilityFront;
|
||||
registerFront(AccessibilityFront);
|
||||
exports.ParentAccessibilityFront = ParentAccessibilityFront;
|
||||
registerFront(ParentAccessibilityFront);
|
||||
exports.SimulatorFront = SimulatorFront;
|
||||
registerFront(SimulatorFront);
|
||||
|
|
|
@ -414,6 +414,19 @@ class RootFront extends FrontClassWithSpec(rootSpec) {
|
|||
this.fronts.set(typeName, front);
|
||||
return front;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function returns true if the root actor has a registered global actor
|
||||
* with a given name.
|
||||
* @param {String} actorName
|
||||
* The name of a global actor.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
async hasActor(actorName) {
|
||||
const rootForm = await this.rootForm;
|
||||
return !!rootForm[actorName + "Actor"];
|
||||
}
|
||||
}
|
||||
exports.RootFront = RootFront;
|
||||
registerFront(RootFront);
|
||||
|
|
|
@ -222,10 +222,12 @@ const accessibilitySpec = generateActorSpec({
|
|||
shutdown: {
|
||||
type: "shutdown",
|
||||
},
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
"can-be-disabled-change": {
|
||||
type: "canBeDisabledChange",
|
||||
canBeDisabled: Arg(0, "boolean"),
|
||||
},
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
"can-be-enabled-change": {
|
||||
type: "canBeEnabledChange",
|
||||
canBeEnabled: Arg(0, "boolean"),
|
||||
|
@ -251,6 +253,40 @@ const accessibilitySpec = generateActorSpec({
|
|||
simulator: RetVal("nullable:simulator"),
|
||||
},
|
||||
},
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
enable: {
|
||||
request: {},
|
||||
response: {},
|
||||
},
|
||||
// TODO: Deprecated. Remove after Fx75.
|
||||
disable: {
|
||||
request: {},
|
||||
response: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const parentAccessibilitySpec = generateActorSpec({
|
||||
typeName: "parentaccessibility",
|
||||
|
||||
events: {
|
||||
"can-be-disabled-change": {
|
||||
type: "canBeDisabledChange",
|
||||
canBeDisabled: Arg(0, "boolean"),
|
||||
},
|
||||
"can-be-enabled-change": {
|
||||
type: "canBeEnabledChange",
|
||||
canBeEnabled: Arg(0, "boolean"),
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
bootstrap: {
|
||||
request: {},
|
||||
response: {
|
||||
state: RetVal("json"),
|
||||
},
|
||||
},
|
||||
enable: {
|
||||
request: {},
|
||||
response: {},
|
||||
|
@ -265,4 +301,5 @@ const accessibilitySpec = generateActorSpec({
|
|||
exports.accessibleSpec = accessibleSpec;
|
||||
exports.accessibleWalkerSpec = accessibleWalkerSpec;
|
||||
exports.accessibilitySpec = accessibilitySpec;
|
||||
exports.parentAccessibilitySpec = parentAccessibilitySpec;
|
||||
exports.simulatorSpec = simulatorSpec;
|
||||
|
|
|
@ -13,7 +13,12 @@
|
|||
// This array should be sorted by `spec` attribute.
|
||||
const Types = (exports.__TypesForTests = [
|
||||
{
|
||||
types: ["accessible", "accessiblewalker", "accessibility"],
|
||||
types: [
|
||||
"accessible",
|
||||
"accessiblewalker",
|
||||
"accessibility",
|
||||
"parentaccessibility",
|
||||
],
|
||||
spec: "devtools/shared/specs/accessibility",
|
||||
front: "devtools/shared/fronts/accessibility",
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче