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

refactor(app): Collect system USB information #5482

Merged
merged 14 commits into from
Apr 28, 2020

Conversation

mcous
Copy link
Contributor

@mcous mcous commented Apr 23, 2020

overview

This PR closes #5358 by adding USB device information collection to the app. See ticket for acceptance criteria.

changelog

  • refactor(app): Collect system USB information

review requests

Functionality should be tested on all three OS's with the enableSystemInfo feature flag on. Simple test plan:

  1. On boot, without U2E adapter plugged in
    • Nothing that special happens, but you should see a list of devices in state.systemInfo.usbDevices
  2. Plug in a Realtek U2E adapter
    • Adapter should show up in state.systemInfo.usbDevices
    • If Windows, device in state should have windowsDriverVersion field set to a string (null means something went wrong)
    • Console log should note an analytics event and an Intercom update adding information about the U2E adapter to the user's analytics profile and to their Intercom profile
    • If Windows, profile information should include driver version
  3. Quit app and relaunch with U2E adapter still plugged in
    • Adapter should show up in state.systemInfo.usbDevices
    • If Windows, device in state should have windowsDriverVersion field set to a string (null means something went wrong)
    • Console log should note an analytics event and an Intercom update adding information about the U2E adapter to the user's analytics profile and to their Intercom profile
    • If Windows, profile information should include driver version
  4. Remove U2E adapter
    • Adapter should be removed from state.systemInfo.usbDevices

risk assessment

Low, feature is currently behind the enableSystemInfo feature flag. Existing Intercom support profile was found to be buggy and un-tested, so I refactored some of it and covered it in tests

@mcous mcous added feature Ticket is a feature request / PR introduces a feature app Affects the `app` project ready for review labels Apr 23, 2020
@mcous mcous requested a review from a team April 23, 2020 21:24
@mcous mcous requested review from a team as code owners April 23, 2020 21:24
@mcous mcous requested review from amitlissack and sanni-t and removed request for a team April 23, 2020 21:24
@mcous
Copy link
Contributor Author

mcous commented Apr 23, 2020

Because the usb-detection module is a native dependency, we're running into an issue building the mac dev build on the Linux CI machine, which is what we currently do for non-release branch builds. We have a few options:

  1. Wait and hope that build(prebuild): update prebuild dependencies to latest MadLittleMods/node-usb-detection#106 gets merged and a new release is pushed, which should mean we can download pre-built binaries at build time rather than build them ourselves
  2. Tweak our CI config to move our branch mac builds to an actual macOS machine
  3. Stop building macOS branch builds

@codecov
Copy link

codecov bot commented Apr 23, 2020

Codecov Report

Merging #5482 into edge will increase coverage by 0.88%.
The diff coverage is 83.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##             edge    #5482      +/-   ##
==========================================
+ Coverage   65.65%   66.54%   +0.88%     
==========================================
  Files        1084     1095      +11     
  Lines       30918    31952    +1034     
==========================================
+ Hits        20300    21262     +962     
- Misses      10618    10690      +72     
Impacted Files Coverage Δ
app-shell/src/main.js 0.00% <ø> (ø)
app/src/config/constants.js 100.00% <ø> (ø)
app/src/epic.js 0.00% <ø> (ø)
app/src/index.js 0.00% <0.00%> (ø)
app/src/reducer.js 0.00% <ø> (ø)
app/src/shell/index.js 100.00% <ø> (ø)
app/src/support/index.js 0.00% <0.00%> (ø)
app/src/support/profile.js 56.00% <56.00%> (ø)
app/src/system-info/reducer.js 87.50% <87.50%> (ø)
app-shell/src/system-info/usb-devices.js 91.30% <91.30%> (ø)
... and 37 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7f7fa08...37f2997. Read the comment docs.

Copy link
Member

@sfoster1 sfoster1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some inline comments

@@ -87,6 +87,8 @@ jobs:
name: 'JS unit tests; build Protocol Designer, Labware Library, Components Library'
# node version pulled from .nvmrc
language: node_js
before_install:
- sudo apt-get install -y --no-install-recommends libudev-dev
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only a build dep, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but hopefully it's unnecessary now that usb-detection is publishing prebuilt binaries for the correct node versions. Still evaluating but will likely updaate the travis config once more

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's some continuing native build shenanigans. For now, it appears we need both the prebuilt binaries and these build dependencies in place for everything to work. My hunch is that there's a problem with the Linux prebuilt binaries.

The usb-detection author appears to be in the middle of a node-gyp upgrade, so I'll take a look at removing these deps when that update is released. Keeping in place right now so we can have successful builds.


const addDriverVersion = (device: Device): Promise<UsbDevice> => {
if (isWindows() && RE_REALTEK.test(device.manufacturer)) {
return getWindowsDriverVersion(device).then(windowsDriverVersion => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll be ok if this gets called for two different devices right? Like if the user has a realtek USB wifi adapter or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why the underlying PowerShell call would care, and the individual device states are separate in the application state, so the results of each individual call will go to the correct place

import type { Action, Dispatch } from '../types'
import type { UsbDeviceMonitor, Device } from './usb-devices'

const RE_REALTEK = /realtek/i
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to see this filtered on vendor ID rather than a string match

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can even bake a VID into the usb-detector command string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoiding locking ourselves to the VID was a conscious decision. IMO we don't have enough information to know that the VID is stable enough to filter on. I'd like to go wide right now and use the analytics info collected (including VID) to verify that we can narrow it down. I've def seen VID / PID shenanigans with counterfeit USB devices in China and I'm sure you've seen the same

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup fair enough

return result
}

export const isRealtekDevice = (device: UsbDevice) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We appear to check for this in a couple different places, could we check it only on the boundary to the usb detector so we can make this log whatever usb devices come through?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This utility function is used to take the wide list of USB devices in state and narrow it down for updating the user's analytics and support profiles with the Realtek information if we see it. For similar reasons to going wide w.r.t. VID, I'd like to go wide on USB devices collection at the state level

If your concern is "this function should log when it sees a Realtek device", then that logging is already happening via MixPanel and Intercom

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit uncomfortable with wide logging of every USB device a user has plugged in to their system, but I guess we don't use it anywhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'd really like to re-evaluate and narrow down once we do have some of that initial data. To be clear, only "realtek" devices get sent up to MixPanel and Intercom. Everything else just sits in state.

There are a few instances where having everything in state could prove useful that I can think of:

Copy link
Contributor

@amitlissack amitlissack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff.

}
}

const decToHex = (number: number) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sooooo functional! ;)

case RobotSettings.FETCH_SETTINGS_SUCCESS:
case RobotSettings.UPDATE_SETTING_SUCCESS:
case Pipettes.FETCH_PIPETTES_SUCCESS: {
const robot = getConnectedRobot(state)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This is a lot of code in a case statement. Perhaps it's justified to be it's own function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's a good call. This was more or less copied over from the previous support profile implementation, it's doing too much, and it's got no unit tests. I'll add a TODO comment + ticket for now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcous mcous removed the request for review from a team April 27, 2020 16:23
@mcous mcous requested review from a team and Kadee80 and removed request for a team April 27, 2020 16:23
Copy link
Contributor

@Kadee80 Kadee80 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🌽

  • code looks sane
  • redux work for init, add, and remove all perform as expected

Copy link
Member

@sanni-t sanni-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍Worked on windows!

Copy link
Contributor

@dozercodes dozercodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works as expected. Tests look good

Copy link
Member

@sfoster1 sfoster1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me on Linux

@mcous mcous merged commit e5a448b into edge Apr 28, 2020
@mcous mcous deleted the app-shell_system-info-collection branch April 28, 2020 17:42
b-cooper pushed a commit that referenced this pull request Apr 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
app Affects the `app` project feature Ticket is a feature request / PR introduces a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: Add system USB info collection to app
6 participants