Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HidServiceEvent not fired during HidService.start #101

Closed
Laivindur opened this issue Sep 7, 2020 · 3 comments
Closed

HidServiceEvent not fired during HidService.start #101

Laivindur opened this issue Sep 7, 2020 · 3 comments
Assignees
Milestone

Comments

@Laivindur
Copy link

Laivindur commented Sep 7, 2020

Hi @gary-rowe

I have realised that, for some reason, when we call hidService.start() by the first time, no HidServiceEvent is handled by the listener.

Here the code I use to start HidService. It's very similar to the one in the project's example

public static void startHIDService() {
		// System info to assist with library detection
		log.info("Platform architecture: " + Platform.ARCH);
		log.info("Resource prefix: " + Platform.RESOURCE_PREFIX);

		// Configure to use custom specification
		HidServicesSpecification hidServicesSpecification = new HidServicesSpecification();
		hidServicesSpecification.setAutoShutdown(true);
		hidServicesSpecification.setScanInterval(500);
		hidServicesSpecification.setPauseInterval(5000);
		hidServicesSpecification.setScanMode(ScanMode.SCAN_AT_FIXED_INTERVAL_WITH_PAUSE_AFTER_WRITE);
	    //HidApi.useLibUsbVariant = false;

		// Get HID services using custom specification
		hidServices = HidManager.getHidServices(hidServicesSpecification);
		hidServices.addHidServicesListener(new HidServicesListener() {

			@Override
			public void hidDeviceAttached(HidServicesEvent event) {
				log.info("Device attached: " + event);

			}

			@Override
			public void hidDeviceDetached(HidServicesEvent event) {
				log.error("Device detached: " + event);

			}

			@Override
			public void hidFailure(HidServicesEvent event) {
				log.error("HID failure: " + event);

			}

		});

		// Start the services
		log.info("Starting HID services.");
		hidServices.start();
	}

Note that, the listener, has not been implemented in the class itself. It's defined on-the-fly by an anonymous class

hidServices.addHidServicesListener(new HidServicesListener() {
...
});

In production, it's a first-citizen class with its own file.

I was expecting that, during the HidService initialization, any HID device already attached will cause a HidServiceEvent. Inspecting hid4java classes, I have found that, somehow, I'm right.

HidService.start() calls HidDeviceManager.start() and ...

public class HidDeviceManager {
...
public void start() {

    // Check for previous start
    if (this.isScanning()) {
      return;
    }

    // Perform a one-off scan to populate attached devices
    scan();

    // Ensure we have a scan thread available
    configureScanThread(getScanRunnable());

  }
...
}

The method scan()

 for (HidDevice attachedDevice : attachedHidDeviceList) {

      if (!this.attachedDevices.containsKey(attachedDevice.getId())) {

        // Device has become attached so add it but do not open
        attachedDevices.put(attachedDevice.getId(), attachedDevice);

        // Fire the event on a separate thread
        listenerList.fireHidDeviceAttached(attachedDevice);

      }
    }

The first time any device is mapped into attachedDevices should result in a new call to stenerList.fireHidDeviceAttached(attachedDevice);

Given the code above, I should see something like this in the console

Platform architecture: x86-64
Resource prefix: linux-x86-64
Starting HID services.
Device attached: HidServicesEvent{hidDevice=HidDevice [path=/dev/hidraw0, vendorId=0x483, productId=0x5750, serialNumber=STM3210, releaseNumber=0x200, manufacturer=STMicroelectronics, product=STM32 Custm HID, usagePage=0x0, usage=0x0, interfaceNumber=0]}
Enumerating attached devices...
HidDevice [path=/dev/hidraw0, vendorId=0x483, productId=0x5750, serialNumber=STM3210, releaseNumber=0x200, manufacturer=STMicroelectronics, product=STM32 Custm HID, usagePage=0x0, usage=0x0, interfaceNumber=0]
Waiting 30s to demonstrate attach/detach handling. Watch for a slow response after write if configured.

Note the output after Starting HID services. starting with Device attached: HidServicesEvent{.

At the moment, the output is

Platform architecture: x86-64
Resource prefix: linux-x86-64
Starting HID services.
Enumerating attached devices...
HidDevice [path=/dev/hidraw0, vendorId=0x483, productId=0x5750, serialNumber=STM3210, releaseNumber=0x200, manufacturer=STMicroelectronics, product=STM32 Custm HID, usagePage=0x0, usage=0x0, interfaceNumber=0]
Waiting 30s to demonstrate attach/detach handling. Watch for a slow response after write if configured.

What am I doing wrong? I'm missing something, but I don't know what

Thank you in advance.

@gary-rowe gary-rowe self-assigned this Sep 9, 2020
gary-rowe added a commit that referenced this issue Sep 9, 2020
@gary-rowe
Copy link
Owner

Hi @Laivindur

Good spot! The HidService code was starting before any listeners were added leading to missed events on startup. However since this has been the default behaviour for a long time I've decided to keep it in place and have an autoStart flag in HidSpecification to drive a manual start process.

I've updated the examples (and added some ANSI colour) to reflect various customisations with a manual start being one of them.

Can you review the changes and see if it fixes this issue for you?

@gary-rowe gary-rowe added the awaiting review This code is awaiting the original creator of the issue to review the solution and provide feedback label Sep 9, 2020
@gary-rowe gary-rowe added this to the Release 0.7.0 milestone Sep 9, 2020
@Laivindur
Copy link
Author

Laivindur commented Sep 10, 2020

Platform architecture: x86-64
Resource prefix: linux-x86-64
Libusb activation: true
�[32mManually starting HID services.�[0m
�[32mEnumerating attached devices...�[0m
�[34mDevice attached: HidServicesEvent{hidDevice=HidDevice [path=0001:0014:00, vendorId=0x483, productId=0x5750, serialNumber=STM3210, releaseNumber=0x200, manufacturer=STMicroelectronics, product=STM32 Custm HID, usagePage=0x0, usage=0x0, interfaceNumber=0]}�[0m
HidDevice [path=0001:0014:00, vendorId=0x483, productId=0x5750, serialNumber=STM3210, releaseNumber=0x200, manufacturer=STMicroelectronics, product=STM32 Custm HID, usagePage=0x0, usage=0x0, interfaceNumber=0]
�[32mWaiting 30s to demonstrate attach/detach handling. Watch for slow response after write if configured.
�[0m

Worked like a charm!

I will upgrade to the new version as soon as it's released.

Thank you for the quick response and fix. It allows me to get rid of ugly walkaround :-)

@gary-rowe gary-rowe added awaiting merge This issue has been reviewed and is ready to merge into a release candidate and removed awaiting review This code is awaiting the original creator of the issue to review the solution and provide feedback labels Sep 10, 2020
@gary-rowe
Copy link
Owner

Thanks for testing it @Laivindur. I'll merge it into develop which should mean that a 0.7.0 release can be done.

@gary-rowe gary-rowe removed the awaiting merge This issue has been reviewed and is ready to merge into a release candidate label Sep 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants