Skip to content

Commit 0c30ecc

Browse files
ert78gbmondalaci
authored andcommitted
feat(device): Read only filled user configuration and fix app close on mac (#486)
* feat(device): Save user configuration length * feat(device): Read only filled user configuration from EEPROM * fix(agent): Close device connections and quit from app on Mac
1 parent fe6cd68 commit 0c30ecc

File tree

5 files changed

+46
-11
lines changed

5 files changed

+46
-11
lines changed

packages/uhk-agent/src/electron-main.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ let appService: AppService;
3939
let sudoService: SudoService;
4040

4141
function createWindow() {
42+
logger.info('[Electron Main] Create new window.');
43+
4244
// Create the browser window.
4345
win = new BrowserWindow({
4446
title: 'UHK Agent',
@@ -73,10 +75,13 @@ function createWindow() {
7375
// Dereference the window object, usually you would store windows
7476
// in an array if your app supports multi windows, this is the time
7577
// when you should delete the corresponding element.
78+
logger.info('[Electron Main] win closed');
7679
win = null;
80+
deviceService.close();
7781
deviceService = null;
7882
appUpdateService = null;
7983
appService = null;
84+
uhkHidDeviceService.close();
8085
uhkHidDeviceService = null;
8186
sudoService = null;
8287
});
@@ -96,11 +101,7 @@ app.on('ready', createWindow);
96101

97102
// Quit when all windows are closed.
98103
app.on('window-all-closed', () => {
99-
// On macOS it is common for applications and their menu bar
100-
// to stay active until the user quits explicitly with Cmd + Q
101-
if (process.platform !== 'darwin') {
102-
app.quit();
103-
}
104+
app.quit();
104105
});
105106

106107
app.on('will-quit', () => {

packages/uhk-agent/src/services/device.service.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,11 @@ export class DeviceService {
8383

8484
try {
8585
this.logService.debug(`[DeviceService] USB[T]: Read ${configName} size from keyboard`);
86-
const configSize = await this.getConfigSizeFromKeyboard(property);
86+
let configSize = await this.getConfigSizeFromKeyboard(property);
8787
const chunkSize = 63;
8888
let offset = 0;
8989
let configBuffer = new Buffer(0);
90+
let firstRead = true;
9091

9192
this.logService.debug(`[DeviceService] USB[T]: Read ${configName} from keyboard`);
9293
while (offset < configSize) {
@@ -95,6 +96,11 @@ export class DeviceService {
9596
const readBuffer = await this.device.write(writeBuffer);
9697
configBuffer = Buffer.concat([configBuffer, new Buffer(readBuffer.slice(1, chunkSizeToRead + 1))]);
9798
offset += chunkSizeToRead;
99+
100+
if (firstRead && config === UsbCommand.ReadUserConfig) {
101+
firstRead = false;
102+
configSize = readBuffer[3] + (readBuffer[4] << 8);
103+
}
98104
}
99105
response = UhkHidDevice.convertBufferToIntArray(configBuffer);
100106
return Promise.resolve(JSON.stringify(response));
@@ -105,6 +111,13 @@ export class DeviceService {
105111
}
106112
}
107113

114+
public close(): void {
115+
this.connected = false;
116+
this.pollTimer$.unsubscribe();
117+
this.logService.info('[DeviceService] Device connection checker stopped.');
118+
119+
}
120+
108121
/**
109122
* HID API not support device attached and detached event.
110123
* This method check the keyboard is attached to the computer or not.

packages/uhk-common/src/config-serializer/config-items/user-configuration.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export class UserConfiguration {
1010
@assertUInt16
1111
dataModelVersion: number;
1212

13+
@assertUInt16
14+
userConfigurationLength: number;
15+
1316
deviceName: string;
1417

1518
moduleConfigurations: ModuleConfiguration[] = [];
@@ -24,6 +27,7 @@ export class UserConfiguration {
2427

2528
fromJsonObject(jsonObject: any): UserConfiguration {
2629
this.dataModelVersion = jsonObject.dataModelVersion;
30+
this.userConfigurationLength = jsonObject.userConfigurationLength;
2731
this.deviceName = jsonObject.deviceName;
2832
this.setDefaultDeviceName();
2933
this.moduleConfigurations = jsonObject.moduleConfigurations.map((moduleConfiguration: any) => {
@@ -35,11 +39,13 @@ export class UserConfiguration {
3539
return macro;
3640
});
3741
this.keymaps = jsonObject.keymaps.map((keymap: any) => new Keymap().fromJsonObject(keymap, this.macros));
42+
this.recalculateConfigurationLength();
3843
return this;
3944
}
4045

4146
fromBinary(buffer: UhkBuffer): UserConfiguration {
4247
this.dataModelVersion = buffer.readUInt16();
48+
this.userConfigurationLength = buffer.readUInt16();
4349
this.deviceName = buffer.readString();
4450
this.setDefaultDeviceName();
4551
this.moduleConfigurations = buffer.readArray<ModuleConfiguration>(uhkBuffer => {
@@ -52,12 +58,18 @@ export class UserConfiguration {
5258
});
5359
this.keymaps = buffer.readArray<Keymap>(uhkBuffer => new Keymap().fromBinary(uhkBuffer, this.macros));
5460
ConfigSerializer.resolveSwitchKeymapActions(this.keymaps);
61+
62+
if (this.userConfigurationLength === 0) {
63+
this.recalculateConfigurationLength();
64+
}
65+
5566
return this;
5667
}
5768

5869
toJsonObject(): any {
5970
return {
6071
dataModelVersion: this.dataModelVersion,
72+
userConfigurationLength: this.userConfigurationLength,
6173
deviceName: this.deviceName,
6274
moduleConfigurations: this.moduleConfigurations.map(moduleConfiguration => moduleConfiguration.toJsonObject()),
6375
keymaps: this.keymaps.map(keymap => keymap.toJsonObject(this.macros)),
@@ -67,6 +79,7 @@ export class UserConfiguration {
6779

6880
toBinary(buffer: UhkBuffer): void {
6981
buffer.writeUInt16(this.dataModelVersion);
82+
buffer.writeUInt16(this.userConfigurationLength);
7083
buffer.writeString(this.deviceName);
7184
buffer.writeArray(this.moduleConfigurations);
7285
buffer.writeArray(this.macros);
@@ -87,6 +100,12 @@ export class UserConfiguration {
87100
return this.macros.find(macro => macroId === macro.id);
88101
}
89102

103+
recalculateConfigurationLength(){
104+
const buffer = new UhkBuffer();
105+
this.toBinary(buffer);
106+
this.userConfigurationLength = buffer.offset;
107+
}
108+
90109
private setDefaultDeviceName(): void {
91110
if (!this.deviceName || this.deviceName.trim().length === 0) {
92111
this.deviceName = 'My UHK';

packages/uhk-usb/src/uhk-hid-device.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,13 @@ export class UhkHidDevice {
157157
* Close the communication chanel with UHK Device
158158
*/
159159
public close(): void {
160+
this.logService.info('[UhkHidDevice] Device communication closing.');
160161
if (!this._device) {
161162
return;
162163
}
163-
164164
this._device.close();
165165
this._device = null;
166+
this.logService.info('[UhkHidDevice] Device communication closed.');
166167
}
167168

168169
public async waitUntilKeyboardBusy(): Promise<void> {
@@ -196,23 +197,23 @@ export class UhkHidDevice {
196197
private connectToDevice(): HID {
197198
try {
198199
const devs = devices();
199-
this.logService.debug('[DeviceService] Available devices:', devs);
200+
this.logService.debug('[UhkHidDevice] Available devices:', devs);
200201

201202
const dev = devs.find((x: Device) =>
202203
x.vendorId === Constants.VENDOR_ID &&
203204
x.productId === Constants.PRODUCT_ID &&
204205
((x.usagePage === 128 && x.usage === 129) || x.interface === 0));
205206

206207
if (!dev) {
207-
this.logService.info('[DeviceService] UHK Device not found:');
208+
this.logService.info('[UhkHidDevice] UHK Device not found:');
208209
return null;
209210
}
210211
const device = new HID(dev.path);
211-
this.logService.info('[DeviceService] Used device:', dev);
212+
this.logService.info('[UhkHidDevice] Used device:', dev);
212213
return device;
213214
}
214215
catch (err) {
215-
this.logService.error('[DeviceService] Can not create device:', err);
216+
this.logService.error('[UhkHidDevice] Can not create device:', err);
216217
}
217218

218219
return null;

packages/uhk-web/src/app/store/effects/user-config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export class UserConfigEffects {
7878
Observable<KeymapAction | MacroAction | RenameUserConfigurationAction>)
7979
.withLatestFrom(this.store.select(getUserConfiguration), this.store.select(getPrevUserConfiguration))
8080
.mergeMap(([action, config, prevUserConfiguration]) => {
81+
config.recalculateConfigurationLength();
8182
this.dataStorageRepository.saveConfig(config);
8283

8384
if (action.type === KeymapActions.REMOVE || action.type === MacroActions.REMOVE) {

0 commit comments

Comments
 (0)