Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dictation_support",
"version": "1.0.5",
"description": "SDK to interact with dictation devices",
"name": "@mouadennasri/dictation_support",
"version": "1.1.0",
"description": "SDK to interact with dictation devices (RADPAIR fork — forwards HIDInputReportEvent.timeStamp to button listeners)",
"scripts": {
"build": "rimraf dist && npx webpack --config=webpack.config.js",
"lint": "eslint --ignore-path .gitignore --ext .ts .",
Expand All @@ -18,9 +18,12 @@
"/dist/index.js",
"/dist/index.d.ts"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/GoogleChromeLabs/dictation_support.git"
"url": "https://github.com/mouadennasri/dictation_support.git"
},
"devDependencies": {
"@types/jasmine": "^4.3.0",
Expand Down
11 changes: 6 additions & 5 deletions src/dictation_device_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ export enum ButtonEvent {
}

export type ButtonEventListener =
(device: DictationDevice, bitMask: ButtonEvent) => void|Promise<void>;
(device: DictationDevice, bitMask: ButtonEvent,
eventTimeStamp: number) => void|Promise<void>;

export abstract class DictationDeviceBase {
private static next_id = 0;
Expand Down Expand Up @@ -117,11 +118,10 @@ export abstract class DictationDeviceBase {
}

protected async onInputReport(event: HIDInputReportEvent) {
const data = event.data;
await this.handleButtonPress(data);
await this.handleButtonPress(event.data, event.timeStamp);
}

protected async handleButtonPress(data: DataView) {
protected async handleButtonPress(data: DataView, eventTimeStamp: number) {
const buttonMappings = this.getButtonMappings();
const inputBitMask = this.getInputBitmask(data);
let outputBitMask = 0;
Expand All @@ -135,7 +135,8 @@ export abstract class DictationDeviceBase {
outputBitMask = this.filterOutputBitMask(outputBitMask);

await Promise.all([...this.buttonEventListeners].map(
listener => listener(this.getThisAsDictationDevice(), outputBitMask)));
listener => listener(
this.getThisAsDictationDevice(), outputBitMask, eventTimeStamp)));
}

protected filterOutputBitMask(outputBitMask: number): number {
Expand Down
13 changes: 8 additions & 5 deletions src/speechmike_hid_device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,17 @@ export class SpeechMikeHidDevice extends DictationDeviceBase {
}
this.proxyDevice = proxyDevice;
this.proxyDevice.addButtonEventListener(
(_device: DictationDevice, bitMask: ButtonEvent) =>
this.onProxyButtonEvent(bitMask));
(_device: DictationDevice, bitMask: ButtonEvent,
eventTimeStamp: number) =>
this.onProxyButtonEvent(bitMask, eventTimeStamp));
}

// See comment in DictationDeviceManager
protected async onProxyButtonEvent(bitMask: ButtonEvent) {
protected async onProxyButtonEvent(
bitMask: ButtonEvent, eventTimeStamp: number) {
await Promise.all([...this.buttonEventListeners].map(
listener => listener(this.getThisAsDictationDevice(), bitMask)));
listener => listener(
this.getThisAsDictationDevice(), bitMask, eventTimeStamp)));
}

protected async handleCommandResponse(command: Command, data: DataView) {
Expand Down Expand Up @@ -360,7 +363,7 @@ export class SpeechMikeHidDevice extends DictationDeviceBase {
const command = data.getUint8(0);

if (command === Command.BUTTON_PRESS_EVENT) {
await this.handleButtonPress(data);
await this.handleButtonPress(data, event.timeStamp);
} else if (command === Command.MOTION_EVENT) {
await this.handleMotionEvent(data);
} else if (command === Command.WIRELESS_STATUS_EVENT) {
Expand Down
7 changes: 5 additions & 2 deletions src/speechmike_hid_device_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,11 +873,14 @@ describe('SpeechMikeHidDevice', () => {

it('propagates button press events from proxy device', async () => {
const button = ButtonEvent.RECORD;
const eventTimeStamp = 1234;
expect(state.buttonEventListener).not.toHaveBeenCalled();
await Promise.all([...state.proxyDicationDeviceButtonEventListeners].map(
listener => listener(state.proxyDicationDevice, button)));
listener =>
listener(state.proxyDicationDevice, button, eventTimeStamp)));
expect(state.buttonEventListener)
.toHaveBeenCalledOnceWith(state.dictationDevice, button);
.toHaveBeenCalledOnceWith(
state.dictationDevice, button, eventTimeStamp);
});
});
});
6 changes: 4 additions & 2 deletions src/test_util/check_button_mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ export async function checkButtonMapping(
expect(buttonEventListener)
.withContext(contextMessageButtonPress)
.toHaveBeenCalledOnceWith(
expectedDicationDevice, testCase.expectedButtonEvents);
expectedDicationDevice, testCase.expectedButtonEvents,
jasmine.any(Number));
}
else {
expect(buttonEventListener)
Expand All @@ -51,7 +52,8 @@ export async function checkButtonMapping(
if (testCase.expectedButtonEvents !== undefined) {
expect(buttonEventListener)
.withContext(contextMessageButtonRelease)
.toHaveBeenCalledOnceWith(expectedDicationDevice, ButtonEvent.NONE);
.toHaveBeenCalledOnceWith(
expectedDicationDevice, ButtonEvent.NONE, jasmine.any(Number));
}
else {
expect(buttonEventListener)
Expand Down
6 changes: 3 additions & 3 deletions src/test_util/fake_hid_device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ export class FakeHidDevice implements HIDDevice {
if (type === 'inputreport') this.inputReportListeners.delete(listener);
}

async handleInputReport(data: number[]) {
async handleInputReport(data: number[], timeStamp = 0) {
const dataView = new DataView(new Uint8Array(data).buffer);
const event: HIDInputReportEvent = {data: dataView} as unknown as
HIDInputReportEvent;
const event: HIDInputReportEvent =
{data: dataView, timeStamp} as unknown as HIDInputReportEvent;
await Promise.all(
[...this.inputReportListeners].map(listener => listener(event)));
}
Expand Down